Skip to content

Commit

Permalink
Change the "Tidy Code" tab of the PGproblemeditor to "Clean Code"
Browse files Browse the repository at this point in the history
This introduces a second option to cleaning code which is convertToPGML, which changes the code in text blocks in the code to use PGML features.
  • Loading branch information
pstaabp committed Jan 12, 2024
1 parent a45ca4b commit 19e96ea
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 21 deletions.
13 changes: 7 additions & 6 deletions htdocs/js/PGProblemEditor/pgproblemeditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@
?.addEventListener('change', () => deleteBackupCheck.checked = true);
}

// Send a request to the server to perltidy the current PG code in the CodeMirror editor.
const tidyPGCode = () => {
// Send a request to the server to either perltidy or convert_to_PGML the current PG code in the CodeMirror editor.
const cleanPGCode = () => {
const request_object = {
user: document.getElementById('hidden_user')?.value,
courseID: document.getElementsByName('courseID')[0]?.value,
key: document.getElementById('hidden_key')?.value
};

request_object.rpc_command = 'tidyPGCode';
request_object.rpc_command = document.querySelector('input[name="action.clean_code"]:checked').value;
request_object.pgCode = webworkConfig?.pgCodeMirror?.getValue()
?? document.getElementById('problemContents')?.value ?? '';

Expand All @@ -132,16 +132,17 @@
if (webworkConfig?.pgCodeMirror) webworkConfig.pgCodeMirror.setValue(data.result_data.tidiedPGCode);
else document.getElementById('problemContents').value = data.result_data.tidiedPGCode;
saveTempFile();
showMessage('Successfuly perltidied code.', true);
showMessage('Successfully '
+ (request_object.rpc_command == 'tidyPGCode' ? 'perltidied code.' : 'converted code to PGML'), true);
}
})
.catch((err) => showMessage(`Error: ${err?.message ?? err}`));
};

document.getElementById('take_action')?.addEventListener('click', async (e) => {
if (document.getElementById('current_action')?.value === 'pgtidy') {
if (document.getElementById('current_action')?.value === 'clean_code') {
e.preventDefault();
tidyPGCode();
cleanPGCode();
return;
}

Expand Down
10 changes: 5 additions & 5 deletions lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ the submit button pressed (the action).
Requested actions and aliases
View/Reload action = view
Generate Hardcopy: action = hardcopy
Tidy Code: action = pgtidy
Clean Code: action = clean_code
Save: action = save
Save as: action = save_as
Append: action = add_problem
Expand All @@ -125,11 +125,11 @@ use WeBWorK::Utils::Instructor qw(assignProblemToAllSetUsers addProblemToSet);
use constant DEFAULT_SEED => 123456;

# Editor tabs
use constant ACTION_FORMS => [qw(view hardcopy pgtidy save save_as add_problem revert)];
use constant ACTION_FORMS => [qw(view hardcopy clean_code save save_as add_problem revert)];
use constant ACTION_FORM_TITLES => {
view => x('View/Reload'),
hardcopy => x('Generate Hardcopy'),
pgtidy => x('Tidy Code'),
clean_code => x('Clean Code'),
save => x('Save'),
save_as => x('Save As'),
add_problem => x('Append'),
Expand Down Expand Up @@ -847,8 +847,8 @@ sub view_handler ($c) {

# The hardcopy and pgtidy actions are handled by javascript. These are provided just in case
# something goes wrong and the actions are called.
sub hardcopy_action { }
sub pgtidy_action { }
sub hardcopy_action { }
sub clean_code_action { }

sub hardcopy_handler ($c) {
# Redirect to problem editor page.
Expand Down
1 change: 1 addition & 0 deletions lib/WebworkWebservice.pm
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ sub command_permission {
putProblemVersion => 'modify_student_data',
putPastAnswer => 'modify_student_data',
tidyPGCode => 'access_instructor_tools',
convertCodeToPGML => 'access_instructor_tools',

# WebworkWebservice::RenderProblem
renderProblem => 'proctor_quiz_login',
Expand Down
15 changes: 15 additions & 0 deletions lib/WebworkWebservice/ProblemActions.pm
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use warnings;
use Data::Structure::Util qw(unbless);

use WeBWorK::PG::Tidy qw(pgtidy);
use Webwork::PG::ConvertToPGML qw(convertToPGML);

sub getUserProblem {
my ($invocant, $self, $params) = @_;
Expand Down Expand Up @@ -146,4 +147,18 @@ sub tidyPGCode {
};
}

sub convertCodeToPGML {
my ($invocant, $self, $params) = @_;
my $code = $params->{pgCode};

# calling convertToPGML($code) without the module path returns an error. Not sure why.
my $converted_code = WeBWorK::PG::ConvertToPGML::convertToPGML($code);

return {
ra_out => { tidiedPGCode => $converted_code },
text => 'Converted to PGML'
};

}

1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<div>
<div class="form-check">
<%= radio_button 'action.clean_code' => 'tidyPGCode',
id => 'action_clean_code_perltidy', class => 'form-check-input', checked => undef =%>
<%= label_for 'action_clean_code_perltidy', class => 'form-check-label', begin =%>
<%== maketext('Reformat the code using perltidy.') =%>
<% end =%>
<a class="help-popup" data-bs-content="<%== maketext('Perltidy is a reformatting '
. 'function that attempts to format code in a standard way. It does not change '
. 'the functionality of the code and in general is desired to have a common problem layout.') =%>"
data-bs-placement="top" data-bs-toggle="popover" role="button">
<i aria-hidden="true" class="icon fas fa-question-circle" data-alt="Help Icon"></i>
<span class="sr-only-glyphicon">Help Icon</span>
</a>
</div>
<div class="form-check">
<%= radio_button 'action.clean_code' => 'convertCodeToPGML',
id => 'action_clean_code_convert_PGML', class => 'form-check-input'=%>
<%= label_for 'action_clean_code_convert_PGML', class => 'form-check-label', begin =%>
<%== maketext('Convert the code to PGML') =%>
<% end =%>
<a class="help-popup" data-bs-content="<%== maketext('This option converts the text blocks '
. 'in the problem code to PGML and updates the loadMacros to include PGML and drop others. '
. 'This can be used as a first pass of the conversion, however the author will still need '
. 'to ensure the problem functions. One area of attention should be the answer blanks, '
. 'which are not converted with the proper variable.') =%>"
data-bs-placement="top" data-bs-toggle="popover" role="button">
<i aria-hidden="true" class="icon fas fa-question-circle" data-alt="Help Icon"></i>
<span class="sr-only-glyphicon">Help Icon</span>
</a>
</div>
</div>

This file was deleted.

12 changes: 7 additions & 5 deletions templates/HelpFiles/InstructorPGProblemEditor.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,14 @@
</p>
</dd>

<dt><%= maketext('Tidy Code') %></dt>
<dt><%= maketext('Clean Code') %></dt>
<dd>
<%= maketext('Reformat the code using perltidy. This will change the code in the editor window, and save '
. 'changes to the temporary file. In some cases (if the code contains backslashes or double tildes) this '
. 'can result in odd spacing in the code. So make sure to inspect the formatted code, and edit further or '
. 'revert if needed.') =%>
<%= maketext('Reformat the code using perltidy or a conversion to PGM>. Using perltidy will change the code '
. ' in the editor window, and save changes to the temporary file. In some cases (if the code contains '
. 'backslashes or double tildes) this can result in odd spacing in the code. The convert to PGML '
. 'feature changes the code in text blocks in the code to use PGML features. Generally the conversion of '
. 'many of the formatting and LaTeX is performed correctly, however answer blanks need attention. In '
. 'either case, make sure to inspect the formatted code, and edit further or revert if needed.') =%>
</dd>

<dt><%= maketext('Save') %></dt>
Expand Down

0 comments on commit 19e96ea

Please sign in to comment.