@@ -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
1322This converts each pg file to PGML formatting. In particular, text blocks are
@@ -16,70 +25,99 @@ =head1 DESCRIPTION
1625
1726Within 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
2237Many 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
2640The C<loadMacros > command is parsed, the C<PGML.pl > is included and C<MathObjects.pl >
2741is removed (because it is loaded by C<PGML.pl > ) and C<PGcourse.pl > is added to the
2842end 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) ;
5074use Getopt::Long;
75+ use Pod::Usage;
5176
5277use lib curfile-> dirname-> dirname . ' /lib' ;
5378
5479use WeBWorK::PG::ConvertToPGML qw( convertToPGML) ;
5580
56- my $backup = 0;
57- my $verbose = 0;
58- my $suffix = ' pgml' ;
59-
6081GetOptions(
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 ' ;
6791convertFile($_ ) for (grep { $_ =~ / \. pg$ / } @ARGV );
6892
6993sub 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
851231;
0 commit comments