Skip to content

Commit 248d50a

Browse files
authored
Merge pull request #1482 from drgrice1/pgml-convert-improvements-revised
Pgml convert improvements revised
2 parents 1059893 + 43bffb9 commit 248d50a

2 files changed

Lines changed: 633 additions & 173 deletions

File tree

bin/convert-to-pgml.pl

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ =head1 SYNOPSIS
88
99
convert-to-pgml -b -s pgml file1.pg file2.pg ...
1010
11+
Options:
12+
13+
-b|--backup Create a backup of the original file before converting.
14+
-e|--extension-prefix=s Extension prefix for the converted files. Default is 'pgml'.
15+
-p|--output-path=s Output directory in which to save the converted problem files.
16+
-v|--verbose Print verbose output.
17+
-h|--help Show the help message.
18+
19+
1120
=head1 DESCRIPTION
1221
1322
This converts each pg file to PGML formatting. In particular, text blocks are
@@ -16,70 +25,99 @@ =head1 DESCRIPTION
1625
1726
Within each block, the following are converted: math modes to their PGML version,
1827
$BR and $PAR to line breaks or empty lines, C<$HR> to C<--->, bold and italics pairs,
19-
any variables of the form C<$var> to C<[$var]>, scripts from \{ \} to [@ @], and C<ans_rule>
20-
to the form C<[_]{}>
28+
any variables of the form C<$var> to C<[$var]>, scripts from \{ \} to [@ @], and
29+
C<< $var->ans_rule() >> to the form C<[_]{$var}>.
30+
31+
A bare C<ans_rule()> call with no answer object cannot be paired with its C<ANS>
32+
call reliably from the source alone, so it is left as a raw Perl call inside a
33+
C<[@ @]> block instead of being converted to a C<[_]{}> answer blank. C<ANS>
34+
commands are never modified or commented out; pairing them with converted or
35+
unconverted answer rules is left entirely to manual review.
2136
2237
Many code features that are no longer needed are removed including
23-
C<TEXT(beginproblem())>, C<<Context()->texStrings;>> and C<<Context()->normalStrings;>>.
24-
Any C<ANS> commands are commented out.
38+
C<TEXT(beginproblem())>, C<< Context()->texStrings; >> and C<< Context()->normalStrings; >>.
2539
2640
The C<loadMacros> command is parsed, the C<PGML.pl> is included and C<MathObjects.pl>
2741
is removed (because it is loaded by C<PGML.pl>) and C<PGcourse.pl> is added to the
2842
end of the list.
2943
30-
Note: many of the features are converted correctly, but often there will be errors
31-
after the conversion. Generally after using this script, the PGML style answers
32-
will need to have their corresponding variable added.
44+
Note: many of the features are converted correctly, but there may be errors
45+
after the conversion. Generally after using this script, the answer rules and
46+
answer evaluators will need to be reviewed and paired up by hand.
3347
3448
=head2 OPTIONS
3549
36-
The option C<-b> or C<--backup> will create a C<.bak> file with the original code and
37-
replace the current file with the converted code.
38-
39-
The option C<-s xyz> or C<--suffix=xyz> will convert the code and write the results in a file
40-
with the given suffix C<xyz> appended to the file name. If this is not given
41-
C<pgml> is used. If the C<-b> flag is used, this option will be ignored.
50+
The option C<-b> or C<--backup> will create a C<.bak> file with the original
51+
code and replace the current file with the converted code.
52+
53+
The option C<-e xyz> or C<--extension-prefix=xyz> will convert the code and
54+
write the results in a file with the given extension prefix C<xyz> before the
55+
C<.pg> extension. If this is not given C<pgml> is used. So, for example, with
56+
the default value of this option, if the file C<problemFile.pg> is converted,
57+
the file C<problemFile.pgml.pg> will be written. If the C<-b> flag is used,
58+
this option will be ignored.
59+
60+
The option C<-p path> or C<--output-path=path> is the location to save the
61+
converted problem files to. If this option is not provided, then the converted
62+
files will be saved in the same directory as the original file. Note that if
63+
this option is used, then the C<-b> or C<--backup> and C<-e> or
64+
C<--extension-prefix> options are ignored unless the path chosen by this option
65+
is the directory containing the original problem file. Also note that if this
66+
option is used, then files in the provided output path will be unconditionally
67+
overwritten unless the file happens to be the original input file.
4268
4369
=cut
4470

45-
use strict;
46-
use warnings;
47-
use experimental 'signatures';
71+
use Mojo::Base -signatures;
4872

49-
use Mojo::File qw(curfile);
73+
use Mojo::File qw(path curfile);
5074
use Getopt::Long;
75+
use Pod::Usage;
5176

5277
use lib curfile->dirname->dirname . '/lib';
5378

5479
use WeBWorK::PG::ConvertToPGML qw(convertToPGML);
5580

56-
my $backup = 0;
57-
my $verbose = 0;
58-
my $suffix = 'pgml';
59-
6081
GetOptions(
61-
"b|backup" => \$backup,
62-
"s|suffix=s" => \$suffix,
63-
"v|verbose" => \$verbose,
82+
'b|backup' => \my $backup,
83+
'e|extension-prefix=s' => \my $extensionPrefix,
84+
'p|output-path=s' => \my $outputPath,
85+
'v|verbose' => \my $verbose,
86+
'h|help' => \my $show_help
6487
);
88+
pod2usage(2) if $show_help || @ARGV == 0;
6589

66-
die 'arguments must have a list of pg files' unless @ARGV > 0;
90+
$extensionPrefix //= 'pgml';
6791
convertFile($_) for (grep { $_ =~ /\.pg$/ } @ARGV);
6892

6993
sub convertFile ($filename) {
70-
my $path = Mojo::File->new($filename);
71-
die "The file: $filename does not exist or is not readable" unless -r $path;
72-
73-
my $pg_source = $path->slurp;
74-
my $converted_source = convertToPGML($pg_source);
75-
76-
# copy the original file to a backup and then write the file
77-
my $new_path = $backup ? $path : Mojo::File->new($filename =~ s/\.pg/.$suffix/r);
94+
my $path = path($filename);
95+
die "The file: $filename does not exist or is not readable.\n" unless -r $path;
96+
97+
my $pg_source = $path->slurp;
98+
my $result = convertToPGML($pg_source);
99+
if ($result->{error}) {
100+
warn "Error parsing $filename. " . $result->{error} . "\n";
101+
return;
102+
}
103+
104+
# If --output-path is given and is not the directory the original file is in, then write to that location.
105+
die qq{The output path "$outputPath" does not exist or is not a directory.\n}
106+
if $outputPath && !-d $outputPath;
107+
if ($outputPath && path($outputPath)->realpath ne $path->dirname->realpath) {
108+
my $new_path = path($outputPath, $path->basename);
109+
$new_path->spurt($result->{pgmlCode});
110+
say "Writing converted file to $new_path" if $verbose;
111+
return;
112+
}
113+
114+
# Copy the original file to a backup and then write the file.
115+
my $new_path = $backup ? $path : path($filename =~ s/\.pg/.$extensionPrefix.pg/r);
78116
my $backup_file = $filename =~ s/\.pg$/.pg.bak/r;
79117
$path->copy_to($backup_file) if $backup;
80-
$new_path->spurt($converted_source);
81-
print "Writing converted file to $new_path\n" if $verbose;
82-
print "Backing up original file to $backup_file\n" if $verbose && $backup;
118+
$new_path->spurt($result->{pgmlCode});
119+
say "Writing converted file to $new_path" if $verbose;
120+
say "Backing up original file to $backup_file" if $verbose && $backup;
83121
}
84122

85123
1;

0 commit comments

Comments
 (0)