From 651fa853669457dbb3da2a9fb587735c383888dd Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Fri, 30 Jun 2023 09:47:46 -0500 Subject: [PATCH] Perltidy improvements The `bin/run-perltidy.pl` script is set up the same as the corresponding webwork2 script to autodetect the pg root directory and no longer depends on the PG_ROOT environment variable. A new perltidyrc file (`bin/perltidy-pg.rc`) is added. This is used for perl tidying pg code. The only differences are that spaces are used for indentation, and a line limit of 80 characters is used instead of 120. The `WeBWorK::PG::Tidy` module is added. This module is a wrapper around the `Perl::Tidy` module that basically does everything the `bin/perltidy-pg.pl` script did before. That script now just calls the exported `pgtidy` method. This module will also be used by the webwork2 PG problem editor to tidy PG problem code. --- .perltidyrc | 42 ++++++++-------- bin/perltidy-pg.pl | 71 ++++---------------------- bin/perltidy-pg.rc | 22 ++++++++ bin/run-perltidy.pl | 18 ++++--- lib/WeBWorK/PG/Tidy.pm | 112 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+), 90 deletions(-) create mode 100644 bin/perltidy-pg.rc create mode 100644 lib/WeBWorK/PG/Tidy.pm diff --git a/.perltidyrc b/.perltidyrc index 4620751c6f..7aff7cafde 100644 --- a/.perltidyrc +++ b/.perltidyrc @@ -1,23 +1,23 @@ # PBP .perltidyrc file --l=120 # Max line width is 120 cols --et=4 # Use tabs instead of spaces. --i=4 # Indent level is 4 cols --ci=4 # Continuation indent is 4 cols --b # Write the file inline and create a .bak file --vt=0 # Minimal vertical tightness --cti=0 # No extra indentation for closing brackets --pt=2 # Maximum parenthesis tightness --bt=1 # Medium brace tightness --sbt=1 # Medium square bracket tightness --bbt=1 # Medium block brace tightness --nsfs # No space before semicolons --nolq # Don't outdent long quoted strings --mbl=1 # Do not allow multiple empty lines --ce # Cuddled else --cb # Cuddled blocks --nbbc # Do not add blank lines before full length comments --nbot # No line break on ternary --nlop # No logical padding (this causes mixed tabs and spaces) --wn # Weld nested containers --xci # Extended continuation indentation +-l=120 # Max line width is 120 cols +-et=4 # Use tabs instead of spaces. +-i=4 # Indent level is 4 cols +-ci=4 # Continuation indent is 4 cols +-b # Write the file inline and create a .bak file +-vt=0 # Minimal vertical tightness +-cti=0 # No extra indentation for closing brackets +-pt=2 # Maximum parenthesis tightness +-bt=1 # Medium brace tightness +-sbt=1 # Medium square bracket tightness +-bbt=1 # Medium block brace tightness +-nsfs # No space before semicolons +-nolq # Don't outdent long quoted strings +-mbl=1 # Do not allow multiple empty lines +-ce # Cuddled else +-cb # Cuddled blocks +-nbbc # Do not add blank lines before full length comments +-nbot # No line break on ternary +-nlop # No logical padding (this causes mixed tabs and spaces) +-wn # Weld nested containers +-xci # Extended continuation indentation -vxl='q' # No vertical alignment of qw quotes diff --git a/bin/perltidy-pg.pl b/bin/perltidy-pg.pl index 0aa76eb0fe..dfd475ebad 100755 --- a/bin/perltidy-pg.pl +++ b/bin/perltidy-pg.pl @@ -20,7 +20,7 @@ =head1 NAME =head1 SYNOPSIS - pg-perltidy.pl [options] file1 file2 ... + pg-perltidy.pl [options] file1 file2 ... =head1 DESCRIPTION @@ -32,9 +32,8 @@ =head1 OPTIONS perltidy documentation for details. Note that if the -pro=file option is not given, then this script will attempt to -use the .perltidyrc file in the PG root directory for this option. For this to -work the PG_ROOT environment variable must be set, and the .perltidyrc file in -the PG root directory must be readable. +use the perltidy-pg.rc file in the PG bin directory for this option. For this to +work the the perltidy-pg.rc file in the PG bin directory must be readable. =cut @@ -42,64 +41,12 @@ =head1 OPTIONS use warnings; use Perl::Tidy; +use Mojo::File qw(curfile); -# Apply the same preprocessing as the PG Translator, except for the removal of everything after ENDDOCUMENT. -my $prefilter = sub { - my $evalString = shift // ''; - - $evalString =~ s/\n\h*END_TEXT[\h;]*\n/\nEND_TEXT\n/g; - $evalString =~ s/\n\h*END_PGML[\h;]*\n/\nEND_PGML\n/g; - $evalString =~ s/\n\h*END_PGML_SOLUTION[\h;]*\n/\nEND_PGML_SOLUTION\n/g; - $evalString =~ s/\n\h*END_PGML_HINT[\h;]*\n/\nEND_PGML_HINT\n/g; - $evalString =~ s/\n\h*END_SOLUTION[\h;]*\n/\nEND_SOLUTION\n/g; - $evalString =~ s/\n\h*END_HINT[\h;]*\n/\nEND_HINT\n/g; - $evalString =~ s/\n\h*BEGIN_TEXT[\h;]*\n/\nSTATEMENT\(EV3P\(<<'END_TEXT'\)\);\n/g; - $evalString =~ s/\n\h*BEGIN_PGML[\h;]*\n/\nSTATEMENT\(PGML::Format2\(<<'END_PGML'\)\);\n/g; - $evalString =~ s/\n\h*BEGIN_PGML_SOLUTION[\h;]*\n/\nSOLUTION\(PGML::Format2\(<<'END_PGML_SOLUTION'\)\);\n/g; - $evalString =~ s/\n\h*BEGIN_PGML_HINT[\h;]*\n/\nHINT\(PGML::Format2\(<<'END_PGML_HINT'\)\);\n/g; - $evalString =~ s/\n\h*BEGIN_SOLUTION[\h;]*\n/\nSOLUTION\(EV3P\(<<'END_SOLUTION'\)\);\n/g; - $evalString =~ s/\n\h*BEGIN_HINT[\h;]*\n/\nHINT\(EV3P\(<<'END_HINT'\)\);\n/g; - $evalString =~ s/\n\h*(.*)\h*->\h*BEGIN_TIKZ[\h;]*\n/\n$1->tex\(<\h*BEGIN_LATEX_IMAGE[\h;]*\n/\n$1->tex\(<tex\(<BEGIN_TIKZ/g; - $evalString =~ s/(.*)->tex\(<BEGIN_LATEX_IMAGE/g; - - # Care is needed to reverse the preprocessing here. - # First in all occurences of an odd number of backslashes the first backslash is replaced with two tildes. - $evalString =~ s/(? \%options); -unshift(@ARGV, "-pro=$ENV{PG_ROOT}/.perltidyrc") - if !defined $options{profile} && defined $ENV{PG_ROOT} && -r "$ENV{PG_ROOT}/.perltidyrc"; - -Perl::Tidy::perltidy(prefilter => $prefilter, postfilter => $postfilter); +use lib curfile->dirname->dirname . '/lib'; + +use WeBWorK::PG::Tidy qw(pgtidy); + +pgtidy(); 1; diff --git a/bin/perltidy-pg.rc b/bin/perltidy-pg.rc new file mode 100644 index 0000000000..a83062e18c --- /dev/null +++ b/bin/perltidy-pg.rc @@ -0,0 +1,22 @@ +# PBP .perltidyrc file +-l=80 # Max line width is 80 cols +-i=4 # Indent level is 4 cols +-ci=4 # Continuation indent is 4 cols +-b # Write the file inline and create a .bak file +-vt=0 # Minimal vertical tightness +-cti=0 # No extra indentation for closing brackets +-pt=2 # Maximum parenthesis tightness +-bt=1 # Medium brace tightness +-sbt=1 # Medium square bracket tightness +-bbt=1 # Medium block brace tightness +-nsfs # No space before semicolons +-nolq # Don't outdent long quoted strings +-mbl=1 # Do not allow multiple empty lines +-ce # Cuddled else +-cb # Cuddled blocks +-nbbc # Do not add blank lines before full length comments +-nbot # No line break on ternary +-nlop # No logical padding (this causes mixed tabs and spaces) +-wn # Weld nested containers +-xci # Extended continuation indentation +-vxl='q' # No vertical alignment of qw quotes diff --git a/bin/run-perltidy.pl b/bin/run-perltidy.pl index 7875d79b05..4b27686728 100755 --- a/bin/run-perltidy.pl +++ b/bin/run-perltidy.pl @@ -28,8 +28,8 @@ =head1 DESCRIPTION =head1 OPTIONS -For this script to work the PG_ROOT environment variable must be set, and the -.perltidyrc file in the PG root directory must be readable. +For this script to work the the .perltidyrc file in the pg root directory +must be readable. Note that the pg root directory is automatically detected. This script accepts all of the options that are accepted by perltidy. See the perltidy documentation for details. @@ -47,7 +47,7 @@ =head1 OPTIONS Finally, if no files are passed on the command line, then perltidy will be executed on all files with the extensions C<.pl>, C<.pm>, or C<.t> in the -PG_ROOT directory. If files are passed on the command line, then perltidy will +pg root directory. If files are passed on the command line, then perltidy will only be executed on the listed files. =cut @@ -58,11 +58,15 @@ =head1 OPTIONS use Perl::Tidy; use File::Find qw(find); +use Mojo::File qw(curfile); + +my $pg_root = curfile->dirname->dirname; die "Version 20220613 or newer of perltidy is required for this script.\n" . "The installed version is $Perl::Tidy::VERSION.\n" unless $Perl::Tidy::VERSION >= 20220613; -die "The pg directory must be defined in PG_ROOT.\n" unless -e $ENV{PG_ROOT} && -r "$ENV{PG_ROOT}/.perltidyrc"; +die "The .perltidyrc file in the pg root directory is not readable.\n" + unless -r "$pg_root/.perltidyrc"; my $verbose = 0; my (@args, @files); @@ -84,7 +88,7 @@ =head1 OPTIONS for (@files) { push(@args, $_); say "Tidying file: $_" if $verbose; - Perl::Tidy::perltidy(argv => \@args, perltidyrc => "$ENV{PG_ROOT}/.perltidyrc"); + Perl::Tidy::perltidy(argv => \@args, perltidyrc => "$pg_root/.perltidyrc"); pop(@args); } } else { @@ -106,12 +110,12 @@ =head1 OPTIONS say "Tidying file: $path" if $verbose; push(@args, $path); - Perl::Tidy::perltidy(argv => \@args, perltidyrc => "$ENV{PG_ROOT}/.perltidyrc"); + Perl::Tidy::perltidy(argv => \@args, perltidyrc => "$pg_root/.perltidyrc"); pop(@args); }, no_chdir => 1 }, - $ENV{PG_ROOT} + $pg_root ); } diff --git a/lib/WeBWorK/PG/Tidy.pm b/lib/WeBWorK/PG/Tidy.pm new file mode 100644 index 0000000000..073839c51a --- /dev/null +++ b/lib/WeBWorK/PG/Tidy.pm @@ -0,0 +1,112 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2023 The WeBWorK Project, https://github.com/openwebwork +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + +=head1 NAME + +WeBWorK::PG::Tidy -- perltidy pg problem files. + +=head1 DESCRIPTION + +perltidy pg problem files. + +=head1 OPTIONS + +This module is a wrapper around Perl::Tidy and just calls C. +Any options passed on the command line are passed to Perl::Tidy::perltidy See +the L documentation for details. + +Note that if the C<-pro=file> option is not given, then this module will attempt +to use the perltidy-pg.rc file in the PG bin directory for this option. For +this to work the perltidy-pg.rc file in the PG bin directory must be readable. + +=cut + +package WeBWorK::PG::Tidy; +use parent qw(Exporter); + +use strict; +use warnings; + +use Perl::Tidy; +use Mojo::File qw(curfile); + +our @EXPORT = qw(pgtidy); + +my $perltidy_pg_rc = curfile->dirname->dirname->dirname->dirname . '/bin/perltidy-pg.rc'; + +# Apply the same preprocessing as the PG Translator, except for the removal of everything after ENDDOCUMENT. +my $prefilter = sub { + my $evalString = shift // ''; + + $evalString =~ s/\n\h*END_TEXT[\h;]*\n/\nEND_TEXT\n/g; + $evalString =~ s/\n\h*END_PGML[\h;]*\n/\nEND_PGML\n/g; + $evalString =~ s/\n\h*END_PGML_SOLUTION[\h;]*\n/\nEND_PGML_SOLUTION\n/g; + $evalString =~ s/\n\h*END_PGML_HINT[\h;]*\n/\nEND_PGML_HINT\n/g; + $evalString =~ s/\n\h*END_SOLUTION[\h;]*\n/\nEND_SOLUTION\n/g; + $evalString =~ s/\n\h*END_HINT[\h;]*\n/\nEND_HINT\n/g; + $evalString =~ s/\n\h*BEGIN_TEXT[\h;]*\n/\nSTATEMENT\(EV3P\(<<'END_TEXT'\)\);\n/g; + $evalString =~ s/\n\h*BEGIN_PGML[\h;]*\n/\nSTATEMENT\(PGML::Format2\(<<'END_PGML'\)\);\n/g; + $evalString =~ s/\n\h*BEGIN_PGML_SOLUTION[\h;]*\n/\nSOLUTION\(PGML::Format2\(<<'END_PGML_SOLUTION'\)\);\n/g; + $evalString =~ s/\n\h*BEGIN_PGML_HINT[\h;]*\n/\nHINT\(PGML::Format2\(<<'END_PGML_HINT'\)\);\n/g; + $evalString =~ s/\n\h*BEGIN_SOLUTION[\h;]*\n/\nSOLUTION\(EV3P\(<<'END_SOLUTION'\)\);\n/g; + $evalString =~ s/\n\h*BEGIN_HINT[\h;]*\n/\nHINT\(EV3P\(<<'END_HINT'\)\);\n/g; + $evalString =~ s/\n\h*(.*)\h*->\h*BEGIN_TIKZ[\h;]*\n/\n$1->tex\(<\h*BEGIN_LATEX_IMAGE[\h;]*\n/\n$1->tex\(<tex\(<BEGIN_TIKZ/g; + $evalString =~ s/(.*)->tex\(<BEGIN_LATEX_IMAGE/g; + + # Care is needed to reverse the preprocessing here. + # First in all occurences of an odd number of backslashes the first backslash is replaced with two tildes. + $evalString =~ s/(? \my %internal_options); + unshift(@ARGV, "-pro=$perltidy_pg_rc") if !defined $internal_options{profile} && -r $perltidy_pg_rc; + + return Perl::Tidy::perltidy(prefilter => $prefilter, postfilter => $postfilter, %options); +} + +1;