diff --git a/lib/WeBWorK/PG/ConvertToPGML.pm b/lib/WeBWorK/PG/ConvertToPGML.pm index 04e4eeddb..dfb9c5e86 100644 --- a/lib/WeBWorK/PG/ConvertToPGML.pm +++ b/lib/WeBWorK/PG/ConvertToPGML.pm @@ -76,6 +76,11 @@ my @ans_list; sub convertToPGML { my ($pg_source) = @_; + # Check that the file is not already in PGML format by looking for PGML.pl in the loadMacros statement. + # and there are no BEGIN_TEXT, BEGIN_SOLUTION, etc. blocks. + + return $pg_source if ($pg_source =~ /loadMacros\((.*)PGML\.pl(.*)\)/ && $pg_source !~ /BEGIN_(TEXT|HINT|SOLUTION)/); + # First get a list of all of the ANS, LABELED_ANS, etc. in the problem. @ans_list = getANS($pg_source); @@ -101,29 +106,67 @@ sub convertToPGML { } elsif ($in_pgml_block) { push(@pgml_block, $row); } elsif ($row =~ /loadMacros\(/) { - # Parse the macros, which may be on multiple rows. - # Remove comments within loadMacros block (should we keep them?) - my $macros = $row; - while ($row && $row !~ /\);\s*$/) { + # Parse the macros, which may be on multiple rows and may be in a qw block. + my $macros = ''; + my $num_macro_lines = 0; # store the number of lines in the loadMacro so the output is similar to the input. + while (1) { + # Remove comments within loadMacros block (should we keep them?) + $row =~ s/#.*$//; + $macros .= $row; + last if ($row =~ /(.*)\);/); + ++$num_macro_lines; $row = shift @rows; - my @mrow = split(/#/, $row); - # This only adds the row if there is something relevent to the left of a # - $macros .= $mrow[0] if $mrow[0] !~ /^\s*$/; } - # Split by commas and pull out the quotes. - my @macros = - grep { $_ !~ /^#/ } - grep { - $_ !~ - /(PGstandard|PGML|PGauxiliaryFunctions|PGbasicmacros|PGanswermacros|MathObjects|PGcourse|AnswerFormatHelp).pl/ + my @macros = (); + my ($qw_start, $qw_end); # the characters if the loadMacros has a qw block. + + # The following can parse loadMacros in the form loadMacros('macro1.pl', 'macro2.pl'); or + # loadMacros(qw{macro1.pl macro2.pl}); + if ($macros =~ /loadMacros\((.*?)\);/ms) { + my @macro_str = split(/\s*,\s*/, $1); + + for my $str (@macro_str) { + if ($str =~ /^qw(.)/) { + my $qw_matches = { '{' => '}', '(' => ')', '[' => ']', '/' => '/', '|' => '|' }; + $qw_start = $1; + $qw_end = $qw_matches->{$qw_start}; + + if ($str =~ /^qw\Q${qw_start}\E(.*?)\Q${qw_end}\E/) { + push(@macros, split(/\s+/, $1)); + } + } else { + push(@macros, $str); + } } - map {s/['"\s]//gr} - split(/\s*,\s*/, $macros =~ s/loadMacros\((.*)\)\;$/$1/r); - push(@all_lines, - 'loadMacros(' - . join(', ', map {"'$_'"} ('PGstandard.pl', 'PGML.pl', @macros, 'PGcourse.pl')) - . ');'); + @macros = + grep { + $_ + && $_ !~ + /(PGstandard|PGML|PGauxiliaryFunctions|PGbasicmacros|PGanswermacros|MathObjects|PGcourse|AnswerFormatHelp).pl/ + } + map {s/['"]//gr} @macros; + + # Remove any duplicates: + my %seen; + @macros = grep { !$seen{$_}++ } @macros; + } else { + warn 'The loadMacros statement in this file could not be processed.'; + } + + @macros = ('PGstandard.pl', 'PGML.pl', @macros, 'PGcourse.pl'); + + if ($qw_start) { + if ($num_macro_lines > 1) { # put each macro on a separate line + push(@all_lines, "loadMacros(qw$qw_start"); + push(@all_lines, "\t$_") for (@macros); + push(@all_lines, "$qw_end);"); + } else { + push(@all_lines, "loadMacros(qw$qw_start" . join(' ', @macros) . "$qw_end);"); + } + } else { + push(@all_lines, 'loadMacros(' . join(', ', map {"'$_'"} @macros) . ');'); + } } else { push(@all_lines, cleanUpCode($row)); }