1717
1818# Mental model, or things that I would liked to know 20 years prior
1919
20- XML Entity processing has more in common with DOMDocumentFragment than
20+ DTD Entity processing has more in common with DOMDocumentFragment than
2121DOMElement. In other words, simple text and multi rooted XML files
2222are valid <!ENTITY> contents, whereas they are not valid XML documents.
2323
2424Also, namespaces do not automatically "cross" between a parent
25- document and their includes , even if they are included in the same
25+ document and their entities , even if they are included in the same
2626file, as local textual entities. <!ENTITY>s are, for all intended
2727purposes, separated documents, with separated namespaces and have
2828*expected* different default namespaces.
3636
3737# Output
3838
39- This script collects bundled and individual entity files (detailed
39+ This script collects grouped and individual entity files (detailed
4040below), at some expected relative paths, and generates an
4141.entities.ent file, in a sibling position to manual.xml.in.
4242
43- The output .entities.ent file has no duplications, so collection
43+ The output file .entities.ent has no duplications, so collection
4444order is important to keep the necessary operational semantics. Here,
4545newer loaded entities takes priority (overwrites) over previous one.
4646Note that this is the reverse of <!ENTITY> convention, where
4949are being overwriten, or if translatable entities are missing
5050translations.
5151
52- # Individual tracked entities , or `.xml` files at `entities/`
52+ # Individual XML Entities , or `.xml` files at `entities/`
5353
5454As explained above, the individual entity contents are not really
5555valid XML *documents*, they are only at most valid XML *fragments*.
5656
5757Yet, individual entities are stored in entities/ as .xml files, for
5858two reasons: first, text editors in general can highlights XML syntax,
59- and second, this allows normal revision tracking on then, without
60- requiring weird changes on `revcheck.php`.
59+ even for XML fragments, and second, this allows normal revision tracking
60+ per file, without requiring weird changes on `revcheck.php`. Note that
61+ is *invalid* to place XML declaration in these fragment files, at least
62+ in files that are invalid XML documents (on multi node rooted ones).
6163
62- # Bundled entities files, group tracked
64+ # Grouped entities files, file tracked
6365
6466For very small textual entities, down to simple text words or single
6567tag elements, that may never change, individual entity tracking is
66- an overkill. This script also loads bundled entities files, at
68+ an overkill. This script also loads grouped XML Entities files, at
6769some expected locations, with specific semantics.
6870
69- These bundle files are really normal XML files, correctly annotated
71+ These grouped files are really normal XML files, correctly annotated
7072with XML namespaces used on manual, so any individual exported entity
71- have corret XML namespace annotations. These bundle entity files
72- are revcheck tracked normaly, but are not included in manual.xml.in,
73- as they only participate in general entity loading, described above.
73+ have correct anc clean XML namespace annotations. These grouped entity
74+ files are tracked normally by revcheck, but are not directly included
75+ in manual.xml.in, as they only participate in general entity loading,
76+ described above.
7477
75- - global.ent - expected untranslated
76- - manual.ent - expected translated
77- - lang/entities/* - expected translated
78+ - global.ent - expected unreplaced
79+ - manual.ent - expected replaced (translated)
80+ - remove.ent - expected unused
81+ - lang/entities/* - expected replaced (translated)
7882
7983*/
8084
85+ const PARTIAL_IMPL = true ; // For while XML Entities are not fully implanted in all languages
86+
8187ini_set ( 'display_errors ' , 1 );
8288ini_set ( 'display_startup_errors ' , 1 );
8389error_reporting ( E_ALL );
8490
85- const PARTIAL_IMPL = true ; // For while spliting and bundle convertion are incomplete
86-
8791if ( count ( $ argv ) < 2 || in_array ( '--help ' , $ argv ) || in_array ( '-h ' , $ argv ) )
8892{
89- fwrite ( STDERR , "\nUsage: {$ argv [0 ]} [--debug] entitiesDir [entitiesDir ] \n\n" );
93+ fwrite ( STDERR , "\nUsage: {$ argv [0 ]} [--debug] langCode [langCode ] \n\n" );
9094 return ;
9195}
9296
93- $ filename = Entities::rotateOutputFile ();
97+ $ filename = Entities::rotateOutputFile (); // idempotent
9498
9599$ langs = [];
96- $ normal = true ; // configure.php mode
97- $ debug = false ; // detailed output
100+ $ normal = true ; // Normal configure.php mode
101+ $ debug = false ; // Detailed console mode
98102
99103for ( $ idx = 1 ; $ idx < count ( $ argv ) ; $ idx ++ )
100104 if ( $ argv [$ idx ] == "--debug " )
125129echo " done: " , Entities::$ countTotalGenerated , " entities " ;
126130if ( Entities::$ countUnstranslated > 0 )
127131 echo ", " , Entities::$ countUnstranslated , " untranslated " ;
128- if ( Entities::$ countConstantReplaced > 0 )
129- echo ", " , Entities::$ countConstantReplaced , " global replaced " ;
130- if ( Entities::$ countRemoveReplaced > 0 )
131- echo ", " , Entities::$ countRemoveReplaced , " to be removed " ;
132+ if ( Entities::$ countReplacedGlobal > 0 )
133+ echo ", " , Entities::$ countReplacedGlobal , " global replaced " ;
134+ if ( Entities::$ countReplacedRemove > 0 )
135+ echo ", " , Entities::$ countReplacedRemove , " remove replaced " ;
132136echo ". \n" ;
133137
134138exit ;
@@ -143,19 +147,19 @@ public function __construct(
143147
144148class Entities
145149{
146- public static int $ countConstantReplaced = 0 ;
147150 public static int $ countUnstranslated = 0 ;
148- public static int $ countRemoveReplaced = 0 ;
151+ public static int $ countReplacedGlobal = 0 ;
152+ public static int $ countReplacedRemove = 0 ;
149153 public static int $ countTotalGenerated = 0 ;
150154
151- private static string $ filename = __DIR__ . "/../. entities.ent " ; // sibling of .manual.xml
155+ private static string $ filename = __DIR__ . "/../temp/ entities.ent " ; // idempotent
152156
153157 private static array $ entities = []; // All entities, overwriten
154- private static array $ global = []; // Entities from global.ent files
158+ private static array $ global = []; // Entities expected not replaced
155159 private static array $ replace = []; // Entities expected replaced / translated
156- private static array $ remove = []; // Entities expected removed
160+ private static array $ remove = []; // Entities expected not replaced and not used
157161 private static array $ count = []; // Name / Count
158- private static array $ slow = []; // External entities, slowless, overwrite
162+ private static array $ slow = []; // External entities, slow, uncontroled overwrite
159163
160164 static function put ( string $ path , string $ name , string $ text , bool $ global = false , bool $ replace = false , bool $ remove = false )
161165 {
@@ -189,7 +193,6 @@ static function rotateOutputFile()
189193 if ( file_exists ( Entities::$ filename ) )
190194 unlink ( Entities::$ filename );
191195 touch ( Entities::$ filename );
192-
193196 Entities::$ filename = realpath ( Entities::$ filename ); // only full paths on XML
194197 }
195198
@@ -201,51 +204,51 @@ static function writeOutputFile()
201204 static function checkReplaces ( bool $ debug )
202205 {
203206 Entities::$ countTotalGenerated = count ( Entities::$ entities );
204- Entities::$ countConstantReplaced = 0 ;
205207 Entities::$ countUnstranslated = 0 ;
206- Entities::$ countRemoveReplaced = 0 ;
208+ Entities::$ countReplacedGlobal = 0 ;
209+ Entities::$ countReplacedRemove = 0 ;
207210
208211 foreach ( Entities::$ entities as $ name => $ text )
209212 {
210213 $ replaced = Entities::$ count [$ name ] - 1 ;
211- $ expectedConstant = in_array ( $ name , Entities::$ global );
214+ $ expectedGlobal = in_array ( $ name , Entities::$ global );
212215 $ expectedReplaced = in_array ( $ name , Entities::$ replace );
213216 $ expectedRemoved = in_array ( $ name , Entities::$ remove );
214217
215- if ( $ expectedConstant && $ replaced != 0 )
218+ if ( $ expectedGlobal && $ replaced != 0 )
216219 {
217- Entities::$ countConstantReplaced ++;
220+ Entities::$ countReplacedGlobal ++;
218221 if ( $ debug )
219- print "Expected global, replaced $ replaced times: \t $ name \n" ;
222+ print "Expected global, replaced $ replaced times: $ name \n" ;
220223 }
221224
222225 if ( $ expectedReplaced && $ replaced != 1 )
223226 {
224227 Entities::$ countUnstranslated ++;
225228 if ( $ debug )
226- print "Expected translated, replaced $ replaced times: \t $ name \n" ;
229+ print "Expected translated, replaced $ replaced times: $ name \n" ;
227230 }
228231
229232 if ( $ expectedRemoved && $ replaced != 0 )
230233 {
231- Entities::$ countRemoveReplaced ++;
234+ Entities::$ countReplacedRemove ++;
232235 if ( $ debug )
233- print "Expected removed, replaced $ replaced times: \t $ name \n" ;
236+ print "Expected removed, replaced $ replaced times: $ name \n" ;
234237 }
235238 }
236239 }
237240}
238241
239242function loadEnt ( string $ path , bool $ global = false , bool $ translate = false , bool $ remove = false , bool $ warnMissing = false )
240243{
241- $ absolute = realpath ( $ path );
242- if ( $ absolute === false )
244+ $ realpath = realpath ( $ path );
245+ if ( $ realpath === false )
243246 if ( PARTIAL_IMPL )
244247 return ;
245248 else
246249 if ( $ warnMissing )
247250 fwrite ( STDERR , "\n Missing entity file: $ path \n" );
248- $ path = $ absolute ;
251+ $ path = $ realpath ;
249252
250253 $ text = file_get_contents ( $ path );
251254 $ text = str_replace ( "& " , "& " , $ text );
@@ -259,7 +262,7 @@ function loadEnt( string $path , bool $global = false , bool $translate = false
259262
260263 foreach ( $ list as $ ent )
261264 {
262- // weird, namespace correting, DOMNodeList -> DOMDocumentFragment
265+ // weird, namespace correting, DOMNodeList -> DOMDocumentFragment transform
263266 $ other = new DOMDocument ( '1.0 ' , 'utf8 ' );
264267
265268 foreach ( $ ent ->childNodes as $ node )
@@ -268,8 +271,8 @@ function loadEnt( string $path , bool $global = false , bool $translate = false
268271 $ name = $ ent ->getAttribute ( "name " );
269272 $ text = $ other ->saveXML ();
270273
271- $ text = str_replace ( "& " , "& " , $ text );
272274 $ text = rtrim ( $ text , "\n" );
275+ $ text = str_replace ( "& " , "& " , $ text );
273276 $ lines = explode ( "\n" , $ text );
274277 array_shift ( $ lines ); // remove XML declaration
275278 $ text = implode ( "\n" , $ lines );
@@ -292,7 +295,7 @@ function loadDir( array $langs , string $lang )
292295 return ;
293296 }
294297 else
295- exit ( "Not directory: $ dir \n" );
298+ exit ( "Error: not a directory: $ dir \n" );
296299
297300 $ files = scandir ( $ dir );
298301 $ expectedReplaced = array_search ( $ lang , $ langs ) > 0 ;
@@ -301,10 +304,10 @@ function loadDir( array $langs , string $lang )
301304 {
302305 $ path = realpath ( "$ dir/ $ file " );
303306
304- if ( is_dir ( $ path ) )
305- continue ;
306307 if ( str_starts_with ( $ file , '. ' ) )
307308 continue ;
309+ if ( is_dir ( $ path ) )
310+ continue ;
308311
309312 $ text = file_get_contents ( $ path );
310313 $ text = rtrim ( $ text , "\n" );
@@ -315,18 +318,17 @@ function loadDir( array $langs , string $lang )
315318
316319function loadXml ( string $ path , string $ text , bool $ expectedReplaced )
317320{
321+ $ info = pathinfo ( $ path );
322+ $ name = $ info ["filename " ];
323+ $ frag = "<frag> $ text</frag> " ;
324+
318325 if ( trim ( $ text ) == "" )
319326 {
320327 fwrite ( STDERR , "\n Empty entity (should it be in remove.ent?): ' $ path' \n" );
321- Entities::put ( $ pat , $ text , remove: true );
328+ Entities::put ( $ path , $ name , $ text );
322329 return ;
323330 }
324331
325- $ info = pathinfo ( $ path );
326- $ name = $ info ["filename " ];
327-
328- $ frag = "<frag> $ text</frag> " ;
329-
330332 $ dom = new DOMDocument ( '1.0 ' , 'utf8 ' );
331333 $ dom ->recover = true ;
332334 $ dom ->resolveExternals = false ;
@@ -354,7 +356,7 @@ function loadXml( string $path , string $text , bool $expectedReplaced )
354356
355357function saveEntitiesFile ( string $ filename , array $ entities )
356358{
357- $ tmpDir = __DIR__ . "/entities " ;
359+ $ tmpDir = __DIR__ . "/temp " ; // idempotent
358360
359361 $ file = fopen ( $ filename , "w " );
360362 fputs ( $ file , "\n<!-- DO NOT COPY / DO NOT TRANSLATE - Autogenerated by entities.php --> \n\n" );
0 commit comments