yihui / knitr

A general-purpose tool for dynamic report generation in R
https://yihui.org/knitr/
2.38k stars 876 forks source link

Support aria-labelledby in htmlwidgets. #2243

Closed dmurdoch closed 1 year ago

dmurdoch commented 1 year ago

This allows htmlwidgets to be labelled with alt text for screen readers.

dmurdoch commented 1 year ago

Fixes #2241

dmurdoch commented 1 year ago

No comments on this yet. Now that I look back at it after 6 weeks, I can see that the explanation is a little lacking.

The issue here is that htmlwidgets don't have any way to handle alt-text for screen readers if it is specified using fig.alt or fig.cur in the chunk options, because those options may be vectors of values to be spread across different figures in the chunk, and the assignment to particular figures happens after the figure is already produced. (It has to be done this way to suppress minor updates to plots.)

This PR handles this by allowing the htmlwidget to put an aria-labelled-by="label" field in the first HTML tag that it emits. The label is generated by the htmlwidget, and found by knitr using the new get_alt_id() function. If there's no id, knitr can assume there's no alt-text needed. If an id is found, then knitr will emit the alt text in the add_html_caption() function, with the id set to the given label. When a screen reader or browser reads the final HTML file, it will know the alt-text for the htmlwidget.

I chose to look only in the first tag of htmlwidgets output because some htmlwidgets (e.g. ones produced by rgl) can be really huge, but I think (almost?) all widgets would have an HTML tag pretty early in their output.

Currently the htmlwidgets package doesn't have specific support for producing these; I've also submitted https://github.com/ramnathv/htmlwidgets/issues/465 to add it there. However, rgl support for this mechanism is already written.

yihui commented 1 year ago

Thanks for the explanation! This has been on my TODO list for a while. I haven't reviewed the PR carefully yet but I think I'll merge it in a few days.