Skip to content
Open
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 75 additions & 22 deletions configure.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,22 @@ function find_file($file_array) // {{{
return '';
} // }}}

function print_dom_errors()
{
$errors = libxml_get_errors();
foreach( $errors as $error )
{
$file = $error->file;
$line = $error->line;
$clmn = $error->column;
$prefix = $error->level === LIBXML_ERR_FATAL ? "FATAL" : "error";
$message = rtrim( $error->message );

if ( $file != '' )
print "[$prefix $file {$line}:{$clmn}] {$message}\n";
}
}

function print_xml_errors()
{
global $ac;
Expand Down Expand Up @@ -290,7 +306,6 @@ function find_xml_files($path) // {{{
'OUTPUT_FILENAME' => $srcdir . '/.manual.xml',
'GENERATE' => 'no',
'STDERR_TO_STDOUT' => 'no',
'INPUT_FILENAME' => 'manual.xml',
'TRANSLATION_ONLY_INCL_BEGIN' => '',
'TRANSLATION_ONLY_INCL_END' => '',
'XPOINTER_REPORTING' => 'yes',
Expand Down Expand Up @@ -530,6 +545,8 @@ function git_clean()
function git_status()
{
global $ac;
if ( $ac['quiet'] == 'yes' )
return;

$repos = array();
$repos['doc-base'] = $ac['basedir'];
Expand All @@ -553,38 +570,73 @@ function git_status()

// DTD entity layer before first XML loading

dtd_conf_entities();
dtd_file_entities();
dtd_text_entities();
dtd_conf_entities();

function dtd_conf_entities()
{
function dtd_pe_body( string $filename = '' )
{
if ( file_exists( $filename ) )
{
$filename = realpain( $filename );
return "SYSTEM '$filename'";
}
return "''";
}

global $ac;
$lang = $ac["LANG"];
$conf = [];

$conf[] = "<!ENTITY LANG '$lang'>";
// When all is converted to XML Entities,
// all this can be reduced to:
// $ent1 = dtd_pe_body( __DIR__ . '/temp/text-entities.ent' );
// $ent2 = dtd_pe_body( __DIR__ . '/temp/file-entities.ent' );

if ( $lang != 'en' )
{
$trans1 = realpain( __DIR__ . "/../$lang/language-defs.ent" );
$trans2 = realpain( __DIR__ . "/../$lang/language-snippets.ent" );
$trans3 = realpain( __DIR__ . "/../$lang/extensions.ent" );
$baseEnt1 = dtd_pe_body( __DIR__ . '/entities/global.ent' );
$baseEnt2 = dtd_pe_body( __DIR__ . '/temp/file-entities.ent' );
$baseEnt3 = dtd_pe_body( __DIR__ . '/temp/entities.ent' );

$conf[] = "<!ENTITY % translation-defs SYSTEM '$trans1'>";
$conf[] = "<!ENTITY % translation-snippets SYSTEM '$trans2'>";
$conf[] = "<!ENTITY % translation-extensions SYSTEM '$trans3'>";
}
$langOne1 = dtd_pe_body( __DIR__ . '/../en/language-defs.ent' );
$langOne2 = dtd_pe_body( __DIR__ . '/../en/language-snippets.ent' );
$langOne3 = dtd_pe_body( __DIR__ . '/../en/extensions.ent' );

if ( $ac['CHMENABLED'] == 'yes' )
if ( $lang == 'en ' )
{
$chmpath = realpain( __DIR__ . "/chm/manual.chm.xml" );
$conf[] = "<!ENTITY manual.chmonly SYSTEM '$chmpath'>";
$langTwo1 = dtd_pe_body();
$langTwo2 = dtd_pe_body();
$langTwo3 = dtd_pe_body();
}
else
$conf[] = "<!ENTITY manual.chmonly ''>";
{
$langTwo1 = dtd_pe_body( __DIR__ . "/../$lang/language-defs.ent" );
$langTwo2 = dtd_pe_body( __DIR__ . "/../$lang/language-snippets.ent" );
$langTwo3 = dtd_pe_body( __DIR__ . "/../$lang/extensions.ent" );
}

file_put_contents( __DIR__ . "/temp/manual.inc" , implode( "\n" , $conf ) );
if ( $ac['CHMENABLED'] == 'yes' )
$chmpath = dtd_pe_body( __DIR__ . "/chm/manual.chm.xml" );
else
$chmpath = dtd_pe_body();

$conf = [];
$conf[] = "<!ENTITY LANG '$lang'>";
$conf[] = "<!ENTITY manual.chmonly $chmpath>";

$conf[] = "<!ENTITY % base-entities $baseEnt1>";
$conf[] = "<!ENTITY % file-entities $baseEnt2>";
$conf[] = "<!ENTITY % text-entities $baseEnt3>";

$conf[] = "<!ENTITY % language-defs $langOne1>";
$conf[] = "<!ENTITY % language-snippets $langOne2>";
$conf[] = "<!ENTITY % language-extensions $langOne3>";

$conf[] = "<!ENTITY % translation-defs $langTwo1>";
$conf[] = "<!ENTITY % translation-snippets $langTwo2>";
$conf[] = "<!ENTITY % translation-extensions $langTwo3>";

file_put_contents( __DIR__ . "/../conf.ent" , implode( "\n" , $conf ) );

@jordikroon jordikroon Jul 21, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break make in docker because this will write to /var/www, not doc-en. Can we perhaps write to temp instead. It's kinda meant for that.

file_put_contents( __DIR__ . "/temp/conf.ent" , implode( "\n" , $conf ) );

with it's companion:

<!ENTITY % configure SYSTEM "../doc-base/temp/conf.ent">.

If this conflicts, we could also write conf-$lang.ent.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break make in docker because this will write to /var/www, not doc-en. Can we perhaps write to temp instead. It's kinda meant for that.

The problem is that temp/ is relative to doc-base, but manual.xml now resides in doc-en. I was trying to remove the sibling restriction, but not considered this usage, and yes, it makes sense for now, as other parts/tools simply require doc-en and doc-base to be siblings. I will change it later.

That said, writing the output in /var/www is ok, but building manuals directly in /var/www is very unsafe, as it exposes all sorts executable scripts into the web. Even in local networks it is unwise to do so. Also permissions will get messy, very fast.

Consider setting up the docker with the internal superuser, but then decaying to a local user when doing any directory creations, git clonage and running build scripts. Only then publishing into /var/www that a superuser may be necessary. Running everything as root may cause all sorts of abnormal errors.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but we should also assume that the docker for development is a tool, and writing to places other than the repositories would create files at places that are not desired.

Alternatively we could create a temp folder in doc-en and add it to gitignore.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add temp/ folder, .gitignor'ed, and changed doc-en side.

}

function dtd_file_entities()
Expand Down Expand Up @@ -652,7 +704,7 @@ function dtd_text_entities()
}
checkvalue($ac["GENERATE"]);

function dom_load( DOMDocument $dom , string $filename , string $baseURI = "" ) : bool
function dom_load( DOMDocument $dom , string $filename , bool $firstLoad ) : bool
{
$filename = realpath( $filename );
$options = LIBXML_NOENT | LIBXML_COMPACT | LIBXML_BIGLINES | LIBXML_PARSEHUGE;
Expand All @@ -666,18 +718,19 @@ function dom_saveload( DOMDocument $dom , string $filename = "" ) : string

libxml_clear_errors();
$dom->save( $filename );
dom_load( $dom , $filename );
dom_load( $dom , $filename , false );

return $filename;
}

echo "Creating monolithic temp/manual.xml... ";
$dom = new DOMDocument();

if ( dom_load( $dom , "{$ac['srcdir']}/{$ac["INPUT_FILENAME"]}" ) )
if ( dom_load( $dom , __DIR__ . '/../en/manual.xml' , true ) )
{
dom_saveload( $dom ); // correct file/line/column on error messages
echo " done.\n";
print_dom_errors();
dom_saveload( $dom ); // correct file/line/column on error messages
}
else
{
Expand Down
Loading