knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(usethis)
Various functions in usethis insert a badge into a package's README file. A badge consists of an image with information about the package, which is usually hyperlinked to a location with further details. Here is a typical badge:
For example, the badge message might be "passing" or "failing", reflecting the R CMD check
status of its current development state, and then link to the actual log file.
Or the badge could display the current test coverage, as a percentage of lines, and then link to a site where one can explore test coverage line-by-line.
A key point is that the badge often presents dynamic information.
We'd like to improve the user experience for those consuming the README using assistive technology, such as a screen reader.
There are at least two ways that usethis can influence this:
This article is meant to gather badge facts in one place and facilitate a dialogue with those using assistive technology.
usethis currently inserts badges in a special "badge block" in the README, fenced with HTML comment tags. Within the badge block, each badge is a hyperlinked image, with alt text. Here is the basic form:
[](http://path/to/more/details)
Note that the alt_text
should be a static label explaining the badge's purpose, whereas the dynamic information is baked into the externally-served image.
usethis definitely controls this alt_text
, so that is something I'd like feedback on.
Most badges these days tend to be SVG files, which is fortunate, since SVGs can carry attributes to support accessibility. We demonstrate this with a custom badge generated via the shields.io web service.
I will request a badge with this URL:
https://img.shields.io/badge/my__label-my__message-orange
Here it is as a badge, with the hyperlink set to https://shields.io/. The badge is inside an HTML comment block, like usethis does for README badges. I've prefixed every field I can influence with "my"; there are 3 such fields:
Now we inspect the badge SVG. I apologize in advance for the amount of data displayed here, but it seems good to show one badge in full gory detail. Later, we will display badge information very selectively.
library(xml2) library(purrr) inspect_badge <- function(badge) { badge %>% read_xml() %>% as_list() %>% pluck("svg") } inspect_badge("https://img.shields.io/badge/my__label-my__message-orange")
It is my understanding that the two main pieces of metadata are the title
and the aria-label
attribute.
Here I reveal just those two items from the badge:
inspect_badge <- function(badge) { x <- badge %>% read_xml() %>% as_list() %>% pluck("svg") list( title = pluck(x, "title", 1), `aria-label` = pluck(x, attr_getter("aria-label")) ) } inspect_badge("https://img.shields.io/badge/my__label-my__message-orange")
This badge carries the same information in the title
and in aria-label
, which is "my_label: my_message".
I would be interested to learn more about why the same information is included twice and if that is a good or bad thing for the screen reader experience.
One of the reasons I inspected a shields.io badge is that this may provide a usable alternative for any service whose official badge is not (yet?) screen-reader-friendly.
The custom badge above is completely static. But shields.io also supports custom dynamic badges, when the necessary information (label, message, color) is available from a suitable JSON endpoint. Finally, and most relevant to usethis, shields.io offers pre-configured dynamic badges for the most commonly "badged" services, including GitHub Actions and Codecov.
Here is a shields.io badge for usethis's R CMD check
workflow on GitHub Actions:
Again, I am indicating fields I control with my_alt_text
and my_label
, so it's easier to get feedback on what usethis should do.
Here is the title
and aria-label
of the badge above:
inspect_badge("https://img.shields.io/github/workflow/status/r-lib/usethis/R-CMD-check?label=my_label-R-CMD-check")
Now we will take inventory of the main badges inserted by usethis and where things stand re: accessibility.
R CMD check
statusWe generally obtain the current R CMD check
status from a GitHub Actions workflow.
Here is the official badge provided by GitHub:
Here is the title
and aria-label
of the badge above:
inspect_badge("https://github.com/r-lib/usethis/actions/workflows/R-CMD-check.yaml/badge.svg")
At the time of writing (late December 2021), the badge does not include such information.
I have requested this in GitHub's Actions and Packages Feedback forum and the response from GitHub is encouraging. Hopefully the native badge will gain improved accessibility early in 2022.
https://github.com/github/feedback/discussions/8974
In the meantime, one could use a shields.io badge to report R CMD check
status, as demonstrated in the previous section.
A maintainer could do this as a one-off or, if the GitHub badge upgrade is slow in coming, we could implement it in usethis::use_github_actions_badge()
.
usethis::use_lifecycle_badge()
declares the developmental stage of a package, using the framework from https://lifecycle.r-lib.org/articles/stages.html.
This function already inserts a shields.io badge:
Here is the title
and aria-label
of the badge above:
inspect_badge("https://img.shields.io/badge/lifecycle-stable-brightgreen.svg")
It's possible that usethis should be using a badge "owned" by the lifecycle package.
I think we don't do so now, because declaring the lifecycle stage of a whole package does not necessarily imply the need to take a formal dependency on the lifecycle package, which is usually what causes badges to be copied into the man/figures/
directory.
Also, the badges shipped by the lifecycle package are not currently accessible, which is another reason not to use them.
But I have opened an issue about this (https://github.com/r-lib/lifecycle/issues/117).
This should be a relatively easy fix, since these are static badges.
Once done, package maintainers would need to update the SVGs that are stored in man/figures/
.
usethis::use_cran_badge()
places a badge that indicates what package version is available on CRAN.
This badge is served by METACRAN (https://www.r-pkg.org) and maintainer Gábor Csárdi has already incorporated aria-label
into the badges (in this commit).
All available badges are listed here.
Here's the badge placed by usethis::use_cran_badge()
:
Here is the title
and aria-label
of the badge above:
inspect_badge("https://www.r-pkg.org/badges/version/usethis")
At the time of writing (late December 2021), aria-label
is present, but title
is not.
I would be interested to know if this is a good situation for those using a screen reader.
usethis::use_coverage(type = c("codecov", "coveralls", ...)
calls the internal helper usethis:::use_codecov_badge()
to insert a badge for either the Codecov or Coveralls service.
Here are examples of those two badges (note that usethis does not use Coveralls, so I'm using a different package to demo):
Here are the title
and aria-label
of those badges::
inspect_badge("https://codecov.io/gh/r-lib/usethis/branch/main/graph/badge.svg") inspect_badge("https://coveralls.io/repos/github/trinker/sentimentr/badge.svg?branch=master")
At the time of writing (late December 2021), neither badge offers a title
or aria-label
.
Here are badges from shields.io for Codecov and Coveralls:
Here are the title
and aria-label
of the shields.io badges::
inspect_badge("https://img.shields.io/codecov/c/github/r-lib/usethis?label=test%20coverage&logo=codecov") inspect_badge("https://img.shields.io/coveralls/github/trinker/sentimentr?logo=coveralls")
If a package is on Bioconductor, usethis::use_bioc_badge()
can be used to insert a badge for its Bioconductor build status.
Here is such a badge:
Here is the title
and aria-label
of that badge:
inspect_badge("http://www.bioconductor.org/shields/build/release/bioc/biocthis.svg")
At the time of writing (late December 2021), the badge does not have a title
or aria-label
.
It's not immediately clear how to resolve this, but I suspect that Bioconductor would be receptive to a request to create more accessible badges.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.