#!/usr/bin/env perl use strict; use warnings; use Getopt::Long qw(:config no_ignore_case); use MIME::Base64 qw(decode_base64); use Mojo::DOM; BEGIN { use Mojo::File; # RENDER_ROOT is required for initializing conf files. $ENV{RENDER_ROOT} = Mojo::File::curfile->dirname->dirname unless ( defined( $ENV{RENDER_ROOT} ) ); # PG_ROOT is required for PG/lib/PGEnvironment.pm, FormatRenderedProblem.pm, and RenderProblem.pm. # This is hardcoded to avoid conflict with the environment variable for webwork2. # There is no need for this to be configurable. $ENV{PG_ROOT} = $ENV{RENDER_ROOT} . '/lib/PG'; $ENV{baseURL} = "standalonerenderer"; } use lib "$ENV{PG_ROOT}/lib"; use lib "$ENV{RENDER_ROOT}/lib"; use WeBWorK::PG; use PGcore; my $help; my $version; my $verbose; my $seed; my $sourceFilePath; my $problemSource; GetOptions( "h|help" => \$help, "V|version" => \$version, "s|seed=i" => \$seed, "p|sourceFilePath=s" => \$sourceFilePath, "c|problemSource=s" => \$problemSource, "v|verbose" => \$verbose, ); if ($help) { print "Usage: $0 --seed= --sourceFilePath= --problemSource=\n"; exit; } if ($version) { print "$ENV{PG_VERSION}\n"; exit; } # check if seed is provided if (!defined $seed) { die "Seed is required\n"; } # either sourceFilePath or problemSource must be provided if (!defined $sourceFilePath && !defined $problemSource) { die "Either sourceFilePath or problemSource must be provided\n"; } my $problemFile; if ($problemSource) { $problemFile = decode_base64($problemSource); } else { $problemFile = Mojo::File->new("$ENV{RENDER_ROOT}/$sourceFilePath")->slurp; } my $inputs_ref = { problemSeed => $seed, sourceFilePath => $sourceFilePath, answersSubmitted => 0, showHints => 1, showSolutions => 1, displayMode => "PTX", answersSubmitted => 0, language => "en", }; my $pg = WeBWorK::PG->new( sourceFilePath => $sourceFilePath, r_source => \$problemFile, problemSeed => $seed, processAnswers => 1, showHints => 1, showSolutions => 1, displayMode => "PTX", # problemNumber => $inputs_ref->{problemNumber}, # ever even relevant? # num_of_correct_ans => $inputs_ref->{numCorrect} || 0, # num_of_incorrect_ans => $inputs_ref->{numIncorrect} || 0, # useMathQuill => !defined $inputs_ref->{entryAssist} || $inputs_ref->{entryAssist} eq 'MathQuill', # answerPrefix => $inputs_ref->{answerPrefix}, # isInstructor => $inputs_ref->{isInstructor}, # forceScaffoldsOpen => $inputs_ref->{forceScaffoldsOpen}, # psvn => $inputs_ref->{psvn}, # problemUUID => $inputs_ref->{problemUUID}, # language => $inputs_ref->{language}, # language_subroutine => WeBWorK::Localize::getLoc($inputs_ref->{language}), inputs_ref => $inputs_ref, templateDirectory => "$ENV{RENDER_ROOT}/", ); # print "rendering $sourceFilePath\n"; # warn "ERRORS: " . $pg->{errors} . "\n" if $verbose; # warn "WARNINGS: " . $pg->{warnings} . "\n" if $verbose; # if ($pg->{pgcore}) { # my $pg_warnings = $pg->{pgcore}->get_warning_messages; # warn "PG: " . join("\n", @$pg_warnings) . "\n" if $verbose; # } else { # die "ERROR caught by Translator while processing problem file:\n" . $pg->{errors} . "\n" . $pg->{warnings} . "\n"; # } # my @resources = map { $_->path } values %{$pg->{pgcore}{PG_alias}{resource_list}}; # print "ASSETS: " . join(", ", @resources ) . "\n"; # Answer hash in XML format used by the PTX format. my $dom = Mojo::DOM->new->xml(1); for my $answer (sort keys %{ $pg->{answers} }) { $dom->append_content($dom->new_tag( $answer, map { $_ => ($pg->{answers}{$answer}{$_} // '') } keys %{ $pg->{answers}{$answer} } )); } $dom->wrap_content(''); my $answerhashXML = $dom->to_string; # regex text for standalonerenderer/pg_files/tmp => RENDER_ROOT/tmp... my $problemText = $pg->{body_text} =~ s/standalonerenderer\/pg_files\/tmp/$ENV{RENDER_ROOT}\/tmp/gr; print sprintf("\n %s\n %s\n\n", $problemText, $answerhashXML, );