#!/usr/bin/perl -T
##
## Generates HTML documentation of error messages and explanations
## for W3C Markup Validation Service
## Pragmas.
use strict;
use warnings;
## Modules. See also the BEGIN block further down below.
use File::Spec::Functions qw(catfile);
use HTML::Template qw(); # Need 2.6 but can't say, rt.cpan.org#70190
use Config::General 2.32 qw(); # Need 2.32 for , rt.cpan.org#17852
use vars qw($DEBUG $CFG $VERSION);
# Define global constants
use constant TRUE => 1;
use constant FALSE => 0;
BEGIN {
my $base = $ENV{W3C_VALIDATOR_HOME} || '/usr/local/validator';
# Launder data for -T; -AutoLaunder doesn't catch this one.
if ($base =~ /^(.*)$/) {
$base = $1;
}
#
# Read Config Files.
eval {
my %config_opts = (
-ConfigFile =>
($ENV{W3C_VALIDATOR_CFG} || '/etc/w3c/validator.conf'),
-MergeDuplicateOptions => TRUE,
-MergeDuplicateBlocks => TRUE,
-SplitPolicy => 'equalsign',
-UseApacheInclude => TRUE,
-IncludeRelative => TRUE,
-InterPolateVars => TRUE,
-AutoLaunder => TRUE,
-AutoTrue => TRUE,
-DefaultConfig => {Paths => {Base => $base,},},
);
my %cfg = Config::General->new(%config_opts)->getall();
$CFG = \%cfg;
};
if ($@) {
die <<"EOF";
Could not read configuration. Set the W3C_VALIDATOR_CFG environment variable
or copy conf/* to /etc/w3c/. Make sure that the configuration file and all
included files are readable by the web server user. The error was:\n'$@'
EOF
}
} # end of BEGIN block.
#
# Get rid of (possibly insecure) $PATH.
delete $ENV{PATH};
our $lang = 'en_US'; # @@@ TODO: conneg
# Read error message + explanations file
our $error_messages_file =
catfile($CFG->{Paths}->{Templates}, $lang, 'error_messages.cfg');
our %config_errs = (
-MergeDuplicateBlocks => 1,
-ConfigFile => $error_messages_file
);
our %rsrc = Config::General->new(%config_errs)->getall();
our $T = HTML::Template->new(
filename => catfile($CFG->{Paths}->{Templates}, $lang, 'docs_errors.tmpl'),
die_on_bad_params => FALSE,
);
$T->param(list_errors_hasverbose => &list_errors_hasverbose(\%rsrc));
$T->param(list_errors_noverbose => &list_errors_noverbose(\%rsrc));
print $T->output;
sub list_errors_hasverbose
{
my $rsrc = shift;
my $errors = [];
my $error_id;
my $max_error_id = 500; # where to stop
for ($error_id = 0; $error_id < $max_error_id; $error_id++) {
my %single_error;
if ($rsrc->{msg}->{$error_id}) {
my $verbose = $rsrc->{msg}->{$error_id}->{verbose};
if ($verbose) {
my $original = $rsrc->{msg}->{$error_id}->{original};
$original = &de_template_explanation($original);
$single_error{original} = $original;
$single_error{id} = $error_id;
$single_error{verbose} = $rsrc->{msg}->{$error_id}->{verbose};
push @{$errors}, \%single_error;
# Fix up relative paths (/check vs /docs/errors.html)
s/href="docs\//href="/
for $single_error{original}, $single_error{verbose};
}
}
}
return $errors;
}
sub list_errors_noverbose
{
my $rsrc = shift;
my $errors = [];
my $error_id;
my $max_error_id = 500; # where to stop
for ($error_id = 0; $error_id < $max_error_id; $error_id++) {
my %single_error;
if ($rsrc->{msg}->{$error_id}) {
my $verbose = $rsrc->{msg}->{$error_id}->{verbose};
if (!$verbose) {
my $original = $rsrc->{msg}->{$error_id}->{original};
$original = &de_template_explanation($original);
$single_error{original} = $original;
$single_error{id} = $error_id;
$single_error{verbose} = $rsrc->{msg}->{$error_id}->{verbose};
push @{$errors}, \%single_error;
}
}
}
return $errors;
}
sub de_template_explanation
{
# takes the error message template, and replace "template keywords" with real life keywords
my $explanation = shift;
if ($explanation) {
$explanation =~ s/\%1/X/;
$explanation =~ s/\%2/Y/;
$explanation =~ s/\%3/Z/;
$explanation =~ s/\%4/a/;
$explanation =~ s/\%5/b/;
$explanation =~ s/\%6/c/;
}
return $explanation;
}
# Local Variables:
# mode: perl
# indent-tabs-mode: nil
# cperl-indent-level: 4
# cperl-continued-statement-offset: 4
# cperl-brace-offset: -4
# perl-indent-level: 4
# End:
# ex: ts=4 sw=4 et