[DOC-CVS] [phd] translatable-acronyms: Read acronyms from translatable acronym.* entities

[email protected] (Jordi Kroon) Wed, 22 Jul 2026 19:33:07 +0000
Newsgroups php.doc.cvs
Message-ID <[email protected]>
Author: Jordi Kroon (jordikroon)
Date: 2026-07-21T21:05:05+02:00

Commit: https://github.com/php/phd/commit/16aca1ef59cba608f264ef27bde8862f112830e8
Raw diff: https://github.com/php/phd/commit/16aca1ef59cba608f264ef27bde8862f112830e8.diff

Read acronyms from translatable acronym.* entities

Changed paths:
  A  tests/package/php/acronym_info_001.phpt
  A  tests/package/php/data/acronyms.ent
  D  tests/package/php/data/acronyms.xml
  M  phpdotnet/phd/Package/PHP/XHTML.php
  M  render.php


Diff:

diff --git a/phpdotnet/phd/Package/PHP/XHTML.php b/phpdotnet/phd/Package/PHP/XHTML.php
index 9e83ed256..11caabf63 100644
--- a/phpdotnet/phd/Package/PHP/XHTML.php
+++ b/phpdotnet/phd/Package/PHP/XHTML.php
@@ -341,26 +341,48 @@ public static function generateAcronymInfo($filename) {
             return array();
         }
 
-        $r = new \XMLReader;
-        if (!$r->open($filename)) {
+        $subset = file_get_contents($filename);
+        if ($subset === false) {
             throw new \Error(vsprintf('Could not open file for accessing acronym information (%s)', [$filename]));
         }
 
-        $acronyms = array();
-        $k = "";
-        while ($r->read()) {
-            if ($r->nodeType != \XMLReader::ELEMENT) {
-                continue;
-            }
-            if ($r->name == "term") {
-                $r->read();
-                $k = $r->value;
-                $acronyms[$k] = "";
-            } else if ($r->name == "simpara") {
-                $r->read();
-                $acronyms[$k] = $r->value;
+        // libxml only exposes entity content once referenced, so collect
+        // the acronym.* entity names first, then reference each of them.
+        $useInternalErrors = libxml_use_internal_errors(true);
+        $dom = new \DOMDocument;
+        $loaded = $dom->loadXML("<!DOCTYPE acronyms [" . $subset . "]><acronyms/>");
+        if (!$loaded) {
+            libxml_clear_errors();
+            libxml_use_internal_errors($useInternalErrors);
+            trigger_error(vsprintf("Can't parse acronym file (%s), skipping", [$filename]), E_USER_WARNING);
+            return [];
+        }
+
+        $names = [];
+        foreach ($dom->doctype->entities as $entity) {
+            if (strncmp($entity->nodeName, "acronym.", 8) === 0) {
+                $names[] = $entity->nodeName;
             }
         }
+
+        $body = "";
+        foreach ($names as $name) {
+            $body .= '<acronym name="' . $name . '">&' . $name . ';</acronym>';
+        }
+        $dom = new \DOMDocument;
+        $loaded = $dom->loadXML("<!DOCTYPE acronyms [" . $subset . "]><acronyms>" . $body . "</acronyms>", LIBXML_NOENT);
+        libxml_clear_errors();
+        libxml_use_internal_errors($useInternalErrors);
+        if (!$loaded) {
+            trigger_error(vsprintf("Can't expand acronym entities (%s), skipping", [$filename]), E_USER_WARNING);
+            return [];
+        }
+
+        $acronyms = [];
+        foreach ($dom->documentElement->childNodes as $node) {
+            $acronyms[substr($node->getAttribute("name"), 8)] = trim(preg_replace('/\s+/', ' ', $node->textContent));
+        }
+        ksort($acronyms);
         $info = $acronyms;
         return $acronyms;
     }
diff --git a/render.php b/render.php
index 94c9e0967..7ef4ae02c 100644
--- a/render.php
+++ b/render.php
@@ -66,7 +66,7 @@
                         . "phd" . DIRECTORY_SEPARATOR . "data" . DIRECTORY_SEPARATOR
                         . "langs" . DIRECTORY_SEPARATOR,
         "phpwebVersionFilename" => $config->xmlRoot . DIRECTORY_SEPARATOR . 'version.xml',
-        "phpwebAcronymFilename" => $config->xmlRoot . DIRECTORY_SEPARATOR . 'entities' . DIRECTORY_SEPARATOR . 'acronyms.xml',
+        "phpwebAcronymFilename" => $config->xmlRoot . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'entities.ent',
         "phpwebSourcesFilename" => $config->xmlRoot . DIRECTORY_SEPARATOR . 'sources.xml',
         "phpwebHistoryFilename" => $config->xmlRoot . DIRECTORY_SEPARATOR . 'fileModHistory.php',
     ));
diff --git a/tests/package/php/acronym_info_001.phpt b/tests/package/php/acronym_info_001.phpt
new file mode 100644
index 000000000..a889d33f7
--- /dev/null
+++ b/tests/package/php/acronym_info_001.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Acronym info 001 - Acronyms are read from acronym.* XML entities
+--FILE--
+<?php
+namespace phpdotnet\phd;
+
+require_once __DIR__ . "/../../setup.php";
+
+$acronyms = Package_PHP_XHTML::generateAcronymInfo(__DIR__ . "/data/acronyms.ent");
+
+var_dump($acronyms);
+?>
+--EXPECT--
+array(4) {
+  ["API"]=>
+  string(33) "Application Programming Interface"
+  ["CSPRNG"]=>
+  string(54) "Cryptographically Secure PseudoRandom Number Generator"
+  ["PHP"]=>
+  string(27) "PHP: Hypertext Preprocessor"
+  ["cURL"]=>
+  string(18) "Client URL Library"
+}
diff --git a/tests/package/php/data/acronyms.ent b/tests/package/php/data/acronyms.ent
new file mode 100644
index 000000000..53eda86bf
--- /dev/null
+++ b/tests/package/php/data/acronyms.ent
@@ -0,0 +1,16 @@
+
+<!-- DO NOT COPY / DO NOT TRANSLATE -->
+<!-- Autogenerated by text-entities.php -->
+
+<!ENTITY sample.other 'Some other, non acronym, entity'>
+
+<!ENTITY acronym.API 'Application Programming Interface'>
+
+<!ENTITY acronym.CSPRNG '
+ Cryptographically Secure
+ PseudoRandom Number Generator
+'>
+
+<!ENTITY acronym.PHP 'PHP: Hypertext Preprocessor'>
+
+<!ENTITY acronym.cURL 'Client URL Library'>
diff --git a/tests/package/php/data/acronyms.xml b/tests/package/php/data/acronyms.xml
deleted file mode 100644
index 0120d0892..000000000
--- a/tests/package/php/data/acronyms.xml
+++ /dev/null
@@ -1,368 +0,0 @@
-<?xml version='1.0' encoding='iso-8859-1'?>
-<!-- $Revision: 283873 $ -->
-
-<!-- All Acronyms should be listed in Alphabetical order -->
-<section xml:id="acronyms">
- <title>Acronyms</title>
- <variablelist>
-  <varlistentry>
-   <term>API</term>
-   <listitem>
-    <simpara>Application Programming Interface</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>ASCII</term>
-   <listitem>
-    <simpara>American Standard Code for Information Interchange</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>BMP</term>
-   <listitem>
-    <simpara>Bitmap</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>CGI</term>
-   <listitem>
-    <simpara>Common Gateway Interface</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>CLI</term>
-   <listitem>
-    <simpara>Command Line Interpreter/Interface</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>CSS</term>
-   <listitem>
-    <simpara>Cascading Style Sheets</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>CSV</term>
-   <listitem>
-    <simpara>Comma Separated Value</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>CVS</term>
-   <listitem>
-    <simpara>Concurrent Versions System</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>DLL</term>
-   <listitem>
-    <simpara>Dynamic Link Library</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>DSSSL</term>
-   <listitem>
-    <simpara>Document Style Semantics and Specification Language</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>EXIF</term>
-   <listitem>
-    <simpara>Exchangeable Image File </simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>EOF</term>
-   <listitem>
-    <simpara>End Of File</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>FAQ</term>
-   <listitem>
-    <simpara>Frequently Asked Questions</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>FTP</term>
-   <listitem>
-    <simpara>File Transfer Protocol</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>GD</term>
-   <listitem>
-    <simpara>Graphics Draw</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>GIF</term>
-   <listitem>
-    <simpara>Graphic Interchange Format</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>GMP</term>
-   <listitem>
-    <simpara>GNU Multiple Precision</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>HIS</term>
-   <listitem>
-    <simpara>Hyperwave Information Server</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>HTML</term>
-   <listitem>
-    <simpara>Hyper Text Markup Language</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>HTTP</term>
-   <listitem>
-    <simpara>Hypertext Transfer Protocol</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>IDE</term>
-   <listitem>
-    <simpara>Integrated Development Environment</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>IFD</term>
-   <listitem>
-    <simpara>Image File Directory</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>IFF</term>
-   <listitem>
-    <simpara>Interchange File Format</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>IMAP</term>
-   <listitem>
-    <simpara>Internet Message Access Protocol</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>JB2</term>
-   <listitem>
-    <simpara>Joint Bilevel Image Experts Group</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>JP2</term>
-   <listitem>
-    <simpara>JPEG-2000</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>JPC</term>
-   <listitem>
-    <simpara>Japan Picture</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>JPEG</term>
-   <listitem>
-    <simpara>Joint Photographic Experts Group</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>MIME</term>
-   <listitem>
-    <simpara>Multipurpose Internet Mail Extensions</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>MP</term>
-   <listitem>
-    <simpara>Multiple Precision</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>MSDN</term>
-   <listitem>
-    <simpara>Microsoft Developer Network</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>NNTP</term>
-   <listitem>
-    <simpara>Network News Transfer Protocol</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>PDF</term>
-   <listitem>
-    <simpara>Portable Document Format</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>PECL</term>
-   <listitem>
-    <simpara>PHP Extension and Application Repository</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>PHP</term>
-   <listitem>
-    <simpara>PHP: Hypertext Preprocessor</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>PNG</term>
-   <listitem>
-    <simpara>Portable Network Graphics</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>POP3</term>
-   <listitem>
-    <simpara>Post Office Protocol version 3</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>POSIX</term>
-   <listitem>
-    <simpara>Portable Operating System Interface</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>PSD</term>
-   <listitem>
-    <simpara>Photoshop Document</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>RGB</term>
-   <listitem>
-    <simpara>Red-Green-Blue</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>SAPI</term>
-   <listitem>
-    <simpara>Server Application Programming Interface</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>SASL</term>
-   <listitem>
-    <simpara>Simple Authentication and Security Layer</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>SWF</term>
-   <listitem>
-    <simpara>Shockwave Flash</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>TCP</term>
-   <listitem>
-    <simpara>Transmission Control Protocol</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>TIFF</term>
-   <listitem>
-    <simpara>Tagged Image File Format</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>TNS</term>
-   <listitem>
-    <simpara>Transparent Network Substrate</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>UDF</term>
-   <listitem>
-    <simpara>User Defined Functions</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>Unicode</term>
-   <listitem>
-    <simpara>Unique, Universal, and Uniform character enCoding</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>URI</term>
-   <listitem>
-    <simpara>Uniform Resource Identifier</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>URL</term>
-   <listitem>
-    <simpara>Uniform Resource Locator</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>WBMP</term>
-   <listitem>
-    <simpara>Wireless Bitmap</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>XBM</term>
-   <listitem>
-    <simpara>X Bitmap</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>XML</term>
-   <listitem>
-    <simpara>eXtensible Markup Language</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>XPath</term>
-   <listitem>
-    <simpara>XML Path Language</simpara>
-   </listitem>
-  </varlistentry>
-  <varlistentry>
-   <term>XSLT</term>
-   <listitem>
-    <simpara>eXtensible Stylesheet Language Transformations</simpara>
-   </listitem>
-  </varlistentry>
-  <!--
-  <varlistentry>
-   <term></term>
-   <listitem>
-    <simpara></simpara>
-   </listitem>
-  </varlistentry>
-  -->
- </variablelist>
-</section>
-
-<!-- Keep this comment at the end of the file
-Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-indent-tabs-mode:nil
-sgml-parent-document:nil
-sgml-default-dtd-file:"../../../../manual.ced"
-sgml-exposed-tags:nil
-sgml-local-catalogs:nil
-sgml-local-ecat-files:nil
-End:
-vim600: syn=xml fen fdm=syntax fdl=2 si
-vim: et tw=78 syn=sgml
-vi: ts=1 sw=1
--->