Skip to content

Add aria labels to PGML and unify their use. - #1493

Draft
somiaj wants to merge 1 commit into
openwebwork:developfrom
somiaj:aria_labels
Draft

Add aria labels to PGML and unify their use.#1493
somiaj wants to merge 1 commit into
openwebwork:developfrom
somiaj:aria_labels

Conversation

@somiaj

@somiaj somiaj commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Update the generate_aria_label method to be given an input label. If the input label is defined and doesn't contain %s, return the label. If the input label is undefined (or blank) generate a default label based on the problem number, answer number, and part number. If the input label contains %s, replace it with the default generated label and return the result.

Update answer rules to more uniformly accept the aria_label option and use the generate_aria_label method. This required updating some and adding the option to others.

Update macros that use the generate_aria_label method to take advantage of the new method. The parserRadioButtons and parserCheckboxList will append "option X" to the end of the generated label. Matrix arrays will append "col N row M" to the end of the generated label.

Update PGML to accept the aria_label option in answer blanks to customize the label, "[_]{$answer}{aria_label => '%s label'}".

The biggest change was in parserRadioMultiAnswer which allows a new option ariaLabels which is the labels to send to the associated answer rules. Update its internal generate_aria_label function to match the changes to the one in PGbasicmacros. In addition the "subpart X" is only added to the label if there are more than one subparts, and the "part Y" will use the label of the part if displayLabels is set, otherwise it uses the number of the part.

This is a more general approach and replacement of #1489. Due to the discussion I am calling the option aria_label to match what was already in the code, label is not a correct name, and accessibility_label is just longer and would require making the code better deal with that. aria_label was already in use and is now just being used more uniformly. aria_label can be used in PGML or sent directly to various ans_rule or ans_array calls.

I went with @dpvc suggestion of allowing a single %s sprintf option to include the default generated label as part of the custom label. To not get any errors from sprintf, I went with just regex find/replace of the first instance of %s in the string.

Here is a problem I was using to test various different checkers and macros. Edit it to remove the aria_label option to check out default generated labels or remove %s to see any effects.

DOCUMENT();
loadMacros(qw(
    PGstandard.pl
    PGML.pl
    parserMultiAnswer.pl
    parserPopUp.pl
    parserRadioMultiAnswer.pl
    parserCheckboxList.pl
    parserRadioButtons.pl
    PGcourse.pl
));
Context('Matrix');
$f     = Compute("7x - 5");
$ma    = MultiAnswer("x + 2", "2x - 3")->with(singleResult => 1);
$M     = Matrix([ [ 2, 0, -3 ], [ -4, -3, -2 ] ]);
$popup = DropDown([ A .. F ], 2, useHTMLSelect => 0);
$rma   = RadioMultiAnswer(
    [
        [ 'Matrix %s*',       Matrix([ [ 0, 1 ], [ 2, 3 ] ]) ],
        [ 'Formula %s',       Formula('x+1') ],
        [ 'Number %s and %s', Compute(5), Compute(-7) ],
        ['No Input']
    ],
    2,
    ariaLabels =>
        [ '%s Matrix', '%s Formula %s', '%s Number1', '%s Number2' ]
);
$checks  = CheckboxList([ A .. F ], [ 2, 5 ]);
$buttons = RadioButtons([ A .. F ], 4);

BEGIN_PGML
[_]{$f}{aria_label => '%s %s function %s'}

[_]{$ma}{aria_label => '%s left hand side'} [`=`] [_]*{$ma}{aria_label => 'right hand side'}

[_]*{$M}{aria_label => '%s augmented matrix'}

[_]{$popup}{aria_label => '%s letter of graph'}

[_]{$rma}{aria_label => '%s radio multi answer'}

[_]{$checks}{aria_label => '%s checkbox list'}

[_]{$buttons}{aria_label => '%s radio buttons'}
END_PGML
ENDDOCUMENT();

Update the `generate_aria_label` method to be given an input label.
If the input label is defined and doesn't contain `%s`, return
the label. If the input label is undefined (or blank) generate
a default label based on the problem number, answer number, and
part number. If the input label contains `%s`, replace it with
the default generated label and return the result.

Update answer rules to more uniformly accept the `aria_label`
option and use the `generate_aria_label` method. This required
updating some and adding the option to others.

Update macros that use the `generate_aria_label` method to take
advantage of the new method. The parserRadioButtons and
parserCheckboxList will append "option X" to the end of the
generated label. Matrix arrays will append "col N row M" to
the end of the generated label.

Update PGML to accept the `aria_label` option in answer blanks
to customize the label, "[_]{$answer}{aria_label => '%s label'}".

The biggest change was in parserRadioMultiAnswer which allows
a new option `ariaLabels` which is the labels to send to the
associated answer rules. Update its internal `generate_aria_label`
function to match the changes to the one in PGbasicmacros. In
addition the "subpart X" is only added to the label if there are
more than one subparts, and the "part Y" will use the label of
the part if `displayLabels` is set, otherwise it uses the number
of the part.
@somiaj
somiaj marked this pull request as draft August 9, 2026 00:52
@somiaj

somiaj commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

@drgrice1 One thing I was unsure about was parserPopUp when the useHTMLSelect => 0 would create an empty visually hidden span that contained the aria_label. I assuming it was correct, but feels weird that the label doesn't wrap the full popup menu being generated.

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.

1 participant