Skip to content

The new problem authoring approach. - #1558

Open
drgrice1 wants to merge 3 commits into
openwebwork:developfrom
drgrice1:authoring-rework
Open

drgrice1 wants to merge 3 commits into
openwebwork:developfrom
drgrice1:authoring-rework

Conversation

@drgrice1

@drgrice1 drgrice1 commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

This sets up a new style of coding problems. These problems must contain a Perl comment block which is essentially a commented out YAML document that has first line ## --- (spacing is ignored) and whose next line declares the pgAuthoringVersion, and is followed by other supported metadata tag values. For example,

## ---
## pgAuthoringVersion: 1
## macros:
##   - parserMultiAnswer.pl
##   - contextFraction.pl
## ---

That block must occur before any line of code, but can be preceded by any number of comment lines or lines consisting entirely of whitespace (so the OPL tags can preceded this block). The keys in this YAML block are case insensitive. So

##---
## pgauthoringversion: 1
## MACROS: [parserPopUp.pl]
##---

will also work. Note that alternate way of giving a YAML array for declaring the macros used by the file.

Problems coded in this new style are not allowed to call DOCUMENT, ENDDOCUMENT, or loadMacros. The problem code is assumed to start at the beginning of the file, and end at the end of the file. The actual DOCUMENT and ENDDOCUMENT calls are added in the WeBWorK::PG::Translator::translate method when the problem code is evaluated. Furthermore, the metadata is passed to the DOCUMENT call. At the end of the DOCUMENT call loadMacros is called and loads the macros PGbasicmacros.pl, PGauxiliaryFunctions.pl, PGML.pl, any macros declared in the macros metadata, and finally the PGcourse.pl macro. So clearly problems should not list PGbasicmacros.pl, PGauxiliaryFunctions.pl, or PGML.pl in the macros metadata (although it would not be an error to do so).

This means that basic problems that do not use any non-core macros will only need to have

## ---
## pgAuthoringVersion: 1
## ---

which is the minimal requirement to signify that this is a problem coded in the new style.

At this point the only valid pgAuthoringVersion is 1, and passing any other version is an error. Of course, the point of a version here is that we can add new authoring versions in the future as authoring coding expectations change, and old versions of problems can continue to work. At this point any problem that does not contain this Perl comment block YAML document with the pgAuthoringVersion declared will continue to work with the old authoring requirements (DOCUMENT and ENDDOCUMENT must be called, and any macros that are needed, including core macros such as PGbasicmacros.pl, loaded via loadMacros).

At this point the only supported metadata keys are pgAuthoringVersion and macros, and it is an error to add anything else. More keys can be added as needed.

Note that this depends on #1548.

…os.pl` versions.

Instead of the `ENDDOCUMENT` method setting the `PROBLEM_GRADER_TO_USE`
flag to the `avg_problem_grader` or `std_problem_grader` methods from
the `PGanswermacros.pl` file (in the case that macro is loaded, or
generally if those methods are defined), the `PROBLEM_GRADER_TO_USE`
environment variable value is simply transferred to the corresponding
flag at that time.  Then the code in `WeBWorK::PG` that already exists
for this takes care of choosing the `WeBWorK::PG::Translator` versions
of those methods instead.  If the `install_problem_grader` method is
used to set the problem grader to code, that is still used as before.

The `std_problem_grader` code is cleaned up and synchronized in both the
`WeBWorK::PG::Translator` package and in the `PGTanswermacros.pl` file,
although the code in the latter will no longer be used.

The POD for both the `std_problem_grader` and `avg_problem_grader`
methods is also copied into the `WeBWorK::PG::Translator` package.

This is the last thing that is needed to make everything in the
`PGanswermacros.pl` either deprecated or unneeded.

This should work with all existing problems since the methods in the
`PGanswermacros.pl` file and the methods in the `WeBWorK::PG::Translator`
package are functionally the same.  Note that those problems that load
the `PGanswermacros.pl` macro (typically via loading `PGstandard.pl`)
and then set the grader via `install_problem_grader(~~&std_problem_grader)`
or `install_problem_grader(~~&avg_problem_grader)` will still be using
the methods from the `PGanswermacros.pl` file.

If instead that macro is NOT loaded, and the grader is set with
`install_problem_grader('std_problem_grader')` or
`install_problem_grader('avg_problem_grader')`, then the
`WeBWorK::PG::Translator` versions will be used. That should be
considered the modern way of doing this. Of course setting the
`avg_problem_grader` is pointless since that is the default. The sample
problems that mention using the `std_problem_grader` have been updated
to use this approach.  You should note that this approach of using the
string instead of the method has actually always worked, and is how this
should have been done along.  It is much nicer than using the `~~&`
construct.
This sets up a new style of coding problems. These problems must contain
a Perl comment block which is essentially a commented out YAML document
that has first line `## ---` (spacing is ignored) and whose next line
declares the `pgAuthoringVersion`, and is followed by other supported
metadata tag values. For example,

```
## ---
## pgAuthoringVersion: 1
## macros:
##   - parserMultiAnswer.pl
##   - contextFraction.pl
## ---
```

That block must occur before any line of code, but can be preceded by
any number of comment lines or lines consisting entirely of whitespace
(so the OPL tags can preceded this block).  The keys in this YAML block
are case insensitive.  So

```
##---
## pgauthoringversion: 1
## MACROS: [parserPopUp.pl]
##---
```

will also work. Note that alternate way of giving a YAML array for
declaring the macros used by the file.

Problems coded in this new style are not allowed to call `DOCUMENT`,
`ENDDOCUMENT`, or `loadMacros`.  The problem code is assumed to start at
the beginning of the file, and end at the end of the file.  The actual
`DOCUMENT` and `ENDDOCUMENT` calls are added in the
`WeBWorK::PG::Translator::translate` method when the problem code is
evaluated.  Furthermore, the metadata is passed to the `DOCUMENT` call.
At the end of the `DOCUMENT` call `loadMacros` is called and loads the
macros `PGbasicmacros.pl`, `PGauxiliaryFunctions.pl`, `PGML.pl`, any
macros declared in the `macros` metadata, and finally the `PGcourse.pl`
macro.  So clearly problems should not list `PGbasicmacros.pl`,
`PGauxiliaryFunctions.pl`, or `PGML.pl` in the `macros` metadata
(although it would not be an error to do so).

This means that basic problems that do not use any non-core macros will
only need to have

```
## ---
## pgAuthoringVersion: 1
## ---
```

which is the minimal requirement to signify that this is a problem coded
in the new style.

At this point the only valid `pgAuthoringVersion` is 1, and passing any
other version is an error. Of course, the point of a version here is
that we can add new authoring versions in the future as authoring coding
expectations change, and old versions of problems can continue to work.
At this point any problem that does not contain this Perl comment block
YAML document with the `pgAuthoringVersion` declared will continue to
work with the old authoring requirements (`DOCUMENT` and `ENDDOCUMENT`
must be called, and any macros that are needed, including core macros
such as `PGbasicmacros.pl`, loaded via `loadMacros`).

At this point the only supported metadata keys are `pgAuthoringVersion`
and `macros`, and it is an error to add anything else. More keys can be
added as needed.
@somiaj

somiaj commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Is the reason to put the metadata in a comment block just to make parsing easier to find start/end of the block and and bail if encountering a non blank/non commented out line? To me not having to include those extra ## characters would be nice.

@drgrice1

drgrice1 commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

The reason it is in a comment block is so that it is valid Perl. Using a __DATA__ section it turns out is not good in a PG problem.

@drgrice1

drgrice1 commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

Furthermore, there are quite a lot of things that would need to be reworked to add an invalid YAML block in the code (the codemirror editor, pg perltidy, pg critic, and probably many other things). Using a Perl comment block already works with everything.

@drgrice1

drgrice1 commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

It is also consistent with the current tagging setup.

@somiaj

somiaj commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Ahh, I keep overlooking it needed to valid perl, since it was being stripped from the file, forgot to consider that.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants