diff --git a/configure.php b/configure.php index c32723fa58..d31fde3e3e 100755 --- a/configure.php +++ b/configure.php @@ -1,9 +1,8 @@ #!/usr/bin/env php | | Hannes Magnusson | | Gwynne Raskind | - | André L F S Bacci | + | André L F S Bacci | +----------------------------------------------------------------------+ */ @@ -27,16 +26,27 @@ echo "configure.php on PHP " . phpversion() . ", libxml " . LIBXML_DOTTED_VERSION . "\n\n"; -// init_argv() -// init_checks() -// init_clean() -// xml_configure() -// xml_parse() -// xml_xinclude() -// xml_validate() -// phd_sources() -// phd_version() -// php_history() +// gereral structure/ordeing for refactoring this code + +// init_parse() // todo: argv parsing into a typed static class, remove all global +// init_check() // todo: move all checks in one place +// init_usage() +// git_clean() partial done +// git_status() partial done +// dtd_conf_entities() done +// dtd_file_entities() done +// dom_load/save() done +// xinclude_byid() done +// xinclude_xpointer() done +// xinclude_residua() done +// xml_partial_output +// xml_validation +// phd_acronym() done +// phd_sources() done +// phd_version() done +// php_history() done + +// ugly: make_scripts_executable const RNG_SCHEMA_DIR = __DIR__ . DIRECTORY_SEPARATOR . 'docbook' . DIRECTORY_SEPARATOR . 'docbook-v5.2-os' . DIRECTORY_SEPARATOR . 'rng' . DIRECTORY_SEPARATOR; const RNG_SCHEMA_FILE = RNG_SCHEMA_DIR . 'docbook.rng'; @@ -573,9 +583,10 @@ function find_xml_files($path) // {{{ $output = str_replace( "\n\n" , "\n" , $output ); echo "\n" , trim( $output ) . "\n\n"; +// DTD configuration before first loading -xml_configure(); -function xml_configure() +dtd_conf_entities(); +function dtd_conf_entities() { global $ac; $lang = $ac["LANG"]; @@ -617,21 +628,28 @@ function xml_configure() globbetyglob("{$ac['basedir']}/scripts", 'make_scripts_executable'); - -{ # file-entities.php - - $cmd = array(); - $cmd[] = $ac['PHP']; - $cmd[] = __DIR__ . "/scripts/file-entities.php"; - if ( $ac["LANG"] != "en" ) - $cmd[] = $ac["LANG"]; - if ( $ac['CHMENABLED'] == 'yes' ) - $cmd[] = '--chmonly'; - foreach ( $cmd as & $part ) +dtd_file_entities(); +function dtd_file_entities() +{ + global $ac; + $lang = $ac["LANG"]; + $withphp = $ac['PHP']; + $withchm = $ac['CHMENABLED'] == 'yes'; + + $parts = array(); + $parts[] = $withphp; + $parts[] = __DIR__ . "/scripts/file-entities.php"; + if ( $lang != "en" ) + $parts[] = $lang; + if ( $withchm ) + $parts[] = '--chmonly'; + + foreach ( $parts as & $part ) $part = escapeshellarg( $part ); + $cmd = implode( ' ' , $parts ); $ret = 0; - $cmd = implode( ' ' , $cmd ); passthru( $cmd , $ret ); + if ( $ret != 0 ) { echo "doc-base/scripts/file-entities.php FAILED.\n"; @@ -656,6 +674,23 @@ function xml_configure() checking('whether to save an invalid .manual.xml'); checkvalue($ac['FORCE_DOM_SAVE']); +echo "Loading and parsing {$ac["INPUT_FILENAME"]}... "; +$dom = new DOMDocument(); + +if ( dom_load( $dom , "{$ac['srcdir']}/{$ac["INPUT_FILENAME"]}" ) ) +{ + echo "1 "; + dom_saveload( $dom ); // correct file/line/column on error messages + echo "2 done.\n"; +} +else +{ + echo "failed.\n"; + print_xml_errors(); + dom_broken_files(); + errors_are_bad(1); +} + function dom_load( DOMDocument $dom , string $filename , string $baseURI = "" ) : bool { $filename = realpath( $filename ); @@ -674,24 +709,7 @@ function dom_saveload( DOMDocument $dom , string $filename = "" ) : string return $filename; } -echo "Loading and parsing {$ac["INPUT_FILENAME"]}... "; -$dom = new DOMDocument(); - -if ( dom_load( $dom , "{$ac['srcdir']}/{$ac["INPUT_FILENAME"]}" ) ) -{ - echo "1 "; - dom_saveload( $dom ); // correct file/line/column on error messages - echo "2 done.\n"; -} -else -{ - echo "failed.\n"; - print_xml_errors(); - individual_xml_broken_check(); - errors_are_bad(1); -} - -function individual_xml_broken_check() +function dom_broken_files() { $cmd = array(); $cmd[] = $GLOBALS['ac']['PHP']; @@ -724,7 +742,7 @@ function individual_xml_broken_check() function xinclude_run_byid( DOMDocument $dom ) { $total = 0; - $maxrun = 10; //LIBXML_VERSION >= 21100 ? 1 : 10; + $maxrun = 10; for( $run = 0 ; $run < $maxrun ; $run++ ) { echo "$run "; @@ -767,7 +785,7 @@ function xinclude_run_byid( DOMDocument $dom ) if ( ! $changed ) return $total; } - echo "XInclude nested too deeply (xml:id).\n"; + echo "XInclude nested too deeply (by xml:id). Update `configure.php`.\n"; errors_are_bad( 1 ); } @@ -791,7 +809,7 @@ function xinclude_run_xpointer( DOMDocument $dom ) : int if ( $was === $now ) return $total; } - echo "XInclude nested too deeply (xpointer).\n"; + echo "XInclude nested too deeply (xpointer). Update `configure.php`.\n"; errors_are_bad( 1 ); } @@ -800,52 +818,54 @@ function xinclude_residual_fixup( DOMDocument $dom ) // XInclude failures are soft errors on translations, so remove // residual XInclude tags on translations to keep them building. - $debugFile = "temp/xinclude-debug.xml"; - $debugPath = __DIR__ . "/{$debugFile}"; - $nodes = xinclude_residual_list( $dom ); + $debugFile1 = "temp/xinclude-fixup-before.xml"; + $debugFile2 = "temp/xinclude-fixup-result.xml"; + $nodes = xinclude_residual_list( $dom ); if ( count( $nodes ) > 0 ) { unset( $nodes ); - dom_saveload( $dom , $debugPath ); - $nodes = $nodes = xinclude_residual_list( $dom ); + dom_saveload( $dom , __DIR__ . "/{$debugFile1}" ); + $nodes = xinclude_residual_list( $dom ); } - $count = 0; + $fixups = 0; $explain = false; foreach( $nodes as $node ) { - if ( $count === 0 ) - { - echo "\nFailed XIncludes, manual parts will be missing."; - echo " Inspect {$debugFile} for context. Failed targets are:\n"; - } - echo "- {$node->getAttribute("xpointer")}\n"; - $count++; - $fixup = null; - $parent = $node->parentNode; - $tagName = $parent->nodeName; - switch( $tagName ) + $parent = $node->parentNode->nodeName; + $target = $node->getAttribute("xpointer"); + $alert = "[Failed XInclude '$target']"; + + if ( $fixups === 0 ) + echo "\nFailed XIncludes, manual parts will be missing. Failed XInclude targets:\n"; + echo "- {$target}\n"; + $fixups++; + + switch( $parent ) { + case "listitem": + $fixup = "$alert"; case "refentry": $fixup = ""; break; case "refsect1": - $fixup = "__"; // https://github.com/php/phd/issues/181 + $fixup = "_$alert"; // https://github.com/php/phd/issues/181 break; case "tbody": - $fixup = ""; + $fixup = "$alert"; break; case "variablelist": - $fixup = ""; + $fixup = "$alert"; break; default: - echo "Unknown parent of failed XInclude: $tagName\n"; + echo " (Unknown parent of failed XInclude: $parent)\n"; $explain = true; continue 2; } + if ( $fixup !== null ) { $other = new DOMDocument( '1.0' , 'utf8' ); @@ -861,22 +881,32 @@ function xinclude_residual_fixup( DOMDocument $dom ) if ( $explain ) { + dom_saveload( $dom , __DIR__ . "/{$debugFile2}" ); + echo << 0 ) + if ( $fixups > 0 ) echo "\n"; - // XInclude by xml:id never duplicates xml:id, horever, also using - // XInclude by XPath/XPointer may start causing duplications - // (see docs/structure.md). Crude and ugly fixup ahead, beware! + // XInclude by xml:id never duplicates xml:id. Horever, using + // XInclude by XPath/XPointer with a XInclude 1.0 library will cause + // xml:id duplication, as xml:id have no special tratament in this version. + // See docs/structure.md for details. + + // Crude and ugly fixup ahead, beware! $list = []; $see = false; @@ -897,12 +927,18 @@ function xinclude_residual_fixup( DOMDocument $dom ) $list[ $id ] = $id; } if ( $see ) - echo " See: https://github.com/php/doc-base/blob/master/docs/structure.md#xmlid-structure\n"; + { + echo "\n See: https://github.com/php/doc-base/blob/master/docs/structure.md#xmlid-structure"; + echo "\n And: https://github.com/php/doc-base/tree/master/scripts/translation"; + echo "\n In special, qaxml-attributes.php and qaxml-entities.php, with and without --urgent."; + echo "\n\n"; + } - $fatal = $GLOBALS['ac']['LANG'] == 'en'; + // Duplicated strucutral xml:ids are fatal on doc-en + $fatal = $GLOBALS['ac']['LANG'] == 'en'; if ( $see && $fatal ) - errors_are_bad( 1 ); // Duplicated strucutral xml:ids are fatal on doc-en + errors_are_bad( 1 ); } function xinclude_residual_list( DOMDocument $dom ) : DOMNodeList @@ -1156,5 +1192,4 @@ function phd_version() CAT; -individual_xml_broken_check(); exit(0); // Finished successfully. diff --git a/scripts/translation/README.md b/scripts/translation/README.md index 4e048c0778..466bd9f847 100644 --- a/scripts/translation/README.md +++ b/scripts/translation/README.md @@ -6,13 +6,13 @@ for inconsistencies. These tools check for structural differences that may cause translation build failures or non-validating DocBook XML results, and fixing these issues will help avoid build failures. -Some checks are less structural, and as not all translations are identical, +Some checks are not strictly structural, and as not all translations are identical, or use the same conventions, they may not be entirely applicable in all languages. Even two translators working on one language may have different opinions on how much synchronization is wanted, so not all scripts will be of use for all translations. -Because of the above, it's possible to silence each alert indempendly. These +Because of the above, it's possible to silence each output indempendly. These scripts will output `--add-ignore` commands that, if executed, will omit the specific alerts in future executions. @@ -25,8 +25,8 @@ or if XML contents are not Unbalanced XML contents are invalid XML and will result in a broken build. BOM and CR marks may not result in broken builds, but *will* cause several -tools below to misbehave, as `libxml` behaviour changes if XML text contains -these bytes. +tools below to misbehave, as *behaviour* of `libxml` itself changes if XML +text contains these bytes. ## qaxml-attributes.php @@ -77,7 +77,7 @@ mismatched tag, to facilitate the work on big files. This script also accepts an `--content=` option, that will check the *contents* of tags, to inspect tags where the contents are expected *not* to -be translated. Example below. +be translated. See example below. ## qaxml-ws.php @@ -95,13 +95,13 @@ locally generated `revcheck.php` status pages. ## Suggested execution -The first execution of these scripts may generate an inordinate amount of -alerts. It's advised to initially run each command separately, and work the +The first execution of these scripts may generate an inordinate amount of +alerts. It's advised to initially run each command separately, and work the alerts on a case by case basis. After all interesting cases are fixed, it's possible to rerun the command and `grep` the output for `--add-ignore` lines, run these commands, and by so, mass ignore the residual alerts. -Structural checks: +Strict structural checks: ``` php doc-base/scripts/broken.php @@ -114,7 +114,7 @@ php doc-base/scripts/translation/qaxml-tags.php --detail php doc-base/scripts/translation/qaxml-ws.php ``` -Tags where is expected no translations: +Tags where is expected **no** translations: ``` php doc-base/scripts/translation/qaxml-tags.php --content=acronym diff --git a/scripts/translation/libqa/ArgvParser.php b/scripts/translation/libqa/ArgvParser.php index 00c4ed9ce9..98bc9584c6 100644 --- a/scripts/translation/libqa/ArgvParser.php +++ b/scripts/translation/libqa/ArgvParser.php @@ -15,8 +15,7 @@ # Description -This class coordinates and centrailzes control for $argv command line -parameters, used between vairous classes. */ +Analysis and consumption of command-line parameters ($argv) */ class ArgvParser { diff --git a/scripts/translation/libqa/OutputBuffer.php b/scripts/translation/libqa/OutputBuffer.php index e1897d41c7..0ce5d03a74 100644 --- a/scripts/translation/libqa/OutputBuffer.php +++ b/scripts/translation/libqa/OutputBuffer.php @@ -15,8 +15,8 @@ # Description -This class caches formatted output, and calculates if this output is not -previously marked as ignored, before printing it. */ +This class caches the formatted output and calculates whether that +output has not been previously marked as ignored before printing it. */ class OutputBuffer { diff --git a/scripts/translation/libqa/OutputIgnore.php b/scripts/translation/libqa/OutputIgnore.php index 21a936a050..62b8d00b94 100644 --- a/scripts/translation/libqa/OutputIgnore.php +++ b/scripts/translation/libqa/OutputIgnore.php @@ -15,8 +15,7 @@ # Description -This class process commands for ignoring outputs, and complement non -ignored outputs with these commands. */ +This class processes commands and tests for omitted local outputs. */ class OutputIgnore { diff --git a/scripts/translation/libqa/SyncFileItem.php b/scripts/translation/libqa/QaxmlPairItem.php similarity index 92% rename from scripts/translation/libqa/SyncFileItem.php rename to scripts/translation/libqa/QaxmlPairItem.php index 2bece482d8..c3091b8b39 100644 --- a/scripts/translation/libqa/SyncFileItem.php +++ b/scripts/translation/libqa/QaxmlPairItem.php @@ -15,11 +15,11 @@ # Description -Holds file related data for synq XML tools. */ +Contains the file path pairs used in all QAXML tools. */ require_once __DIR__ . '/all.php'; -class SyncFileItem +class QaxmlPairItem { public string $sourceDir; public string $targetDir; diff --git a/scripts/translation/libqa/SyncFileList.php b/scripts/translation/libqa/QaxmlPairList.php similarity index 86% rename from scripts/translation/libqa/SyncFileList.php rename to scripts/translation/libqa/QaxmlPairList.php index 35caee99f2..165ab5b30a 100644 --- a/scripts/translation/libqa/SyncFileList.php +++ b/scripts/translation/libqa/QaxmlPairList.php @@ -15,11 +15,11 @@ # Description -Generates (and caches) the list of files with TranslatedOk status. */ +Generates and caches the list of file path pairs used QAXML tools. */ require_once __DIR__ . '/all.php'; -class SyncFileList +class QaxmlPairList { static function load( ?string $lang = null , array $filterFiles = [] ) { @@ -28,7 +28,7 @@ static function load( ?string $lang = null , array $filterFiles = [] ) $file = __DIR__ . "/../../../temp/lang"; if ( ! file_exists( $file ) ) { - fwrite( STDERR , "Language not found, run 'doc-base/configure.php' or use '--lang='.\n" ); + fwrite( STDERR , "Language to process. Run 'doc-base/configure.php' or use '--lang='.\n" ); exit(); } $lang = trim( file_get_contents( $file ) ); @@ -45,13 +45,13 @@ static function load( ?string $lang = null , array $filterFiles = [] ) { if ( ! file_exists( "$sourceDir/$file" ) ) { - fwrite( STDERR , "File not found in source: $sourceDir/$file\n" ); + fwrite( STDERR , "File not found on source side, ignored: $sourceDir/$file\n" ); continue; } if ( ! file_exists( "$targetDir/$file" ) ) continue; - $item = new SyncFileItem(); + $item = new QaxmlPairItem(); $item->sourceDir = $sourceDir; $item->targetDir = $targetDir; $item->file = $file; @@ -64,12 +64,10 @@ static function load( ?string $lang = null , array $filterFiles = [] ) return $ret; } - $cacheFilename = __DIR__ . "/../../../temp/qaxml.files.$lang"; + $cacheFilename = __DIR__ . "/../../../temp/qaxml.pairs.$lang.gz"; if ( file_exists( $cacheFilename ) ) - { return unserialize( gzdecode( file_get_contents( $cacheFilename ) ) ); - } require_once __DIR__ . '/../lib/all.php'; @@ -81,7 +79,7 @@ static function load( ?string $lang = null , array $filterFiles = [] ) if ( ! file_exists( "$targetDir/{$file->file}" ) ) continue; - $item = new SyncFileItem(); + $item = new QaxmlPairItem(); $item->sourceDir = $sourceDir; $item->targetDir = $targetDir; $item->file = $file->file; diff --git a/scripts/translation/libqa/all.php b/scripts/translation/libqa/all.php index ef24410751..13864570f0 100644 --- a/scripts/translation/libqa/all.php +++ b/scripts/translation/libqa/all.php @@ -19,8 +19,8 @@ error_reporting( E_ALL ); require_once __DIR__ . '/ArgvParser.php'; +require_once __DIR__ . '/QaxmlPairList.php'; +require_once __DIR__ . '/QaxmlPairItem.php'; require_once __DIR__ . '/OutputBuffer.php'; require_once __DIR__ . '/OutputIgnore.php'; -require_once __DIR__ . '/SyncFileList.php'; -require_once __DIR__ . '/SyncFileItem.php'; require_once __DIR__ . '/XmlFrag.php'; diff --git a/scripts/translation/qaxml-attributes.php b/scripts/translation/qaxml-attributes.php index df6eb0e75c..b3f449714f 100644 --- a/scripts/translation/qaxml-attributes.php +++ b/scripts/translation/qaxml-attributes.php @@ -32,7 +32,7 @@ } $argv->complete(); -$list = SyncFileList::load( $lang , $files ); +$list = QaxmlPairList::load( $lang , $files ); foreach ( $list as $file ) { diff --git a/scripts/translation/qaxml-entities.php b/scripts/translation/qaxml-entities.php index cfe473bbe7..e494577678 100644 --- a/scripts/translation/qaxml-entities.php +++ b/scripts/translation/qaxml-entities.php @@ -41,7 +41,7 @@ } $argv->complete(); -$list = SyncFileList::load( $lang , $files ); +$list = QaxmlPairList::load( $lang , $files ); foreach ( $list as $file ) { diff --git a/scripts/translation/qaxml-pi.php b/scripts/translation/qaxml-pi.php index e9b1acab23..d96e739995 100644 --- a/scripts/translation/qaxml-pi.php +++ b/scripts/translation/qaxml-pi.php @@ -31,7 +31,7 @@ } $argv->complete(); -$list = SyncFileList::load( $lang , $files ); +$list = QaxmlPairList::load( $lang , $files ); foreach ( $list as $file ) { diff --git a/scripts/translation/qaxml-revtag.php b/scripts/translation/qaxml-revtag.php index 7d8862ed61..638e59fb05 100644 --- a/scripts/translation/qaxml-revtag.php +++ b/scripts/translation/qaxml-revtag.php @@ -33,7 +33,7 @@ } $argv->complete(); -$list = SyncFileList::load( $lang , $files ); +$list = QaxmlPairList::load( $lang , $files ); foreach ( $list as $file ) { diff --git a/scripts/translation/qaxml-tags.php b/scripts/translation/qaxml-tags.php index 910c091301..d78ac21baf 100644 --- a/scripts/translation/qaxml-tags.php +++ b/scripts/translation/qaxml-tags.php @@ -36,7 +36,7 @@ if ( count( $tags ) == 1 && $tags[0] == "" ) $tags = []; -$list = SyncFileList::load( $lang , $files ); +$list = QaxmlPairList::load( $lang , $files ); foreach ( $list as $file ) { diff --git a/scripts/translation/qaxml-ws.php b/scripts/translation/qaxml-ws.php index a44fd99a8c..c5dc5db01d 100644 --- a/scripts/translation/qaxml-ws.php +++ b/scripts/translation/qaxml-ws.php @@ -32,7 +32,7 @@ } $argv->complete(); -$list = SyncFileList::load( $lang , $files ); +$list = QaxmlPairList::load( $lang , $files ); foreach ( $list as $file ) {