Skip to content

Commit fae9946

Browse files
authored
W3C Accessibility Metadata Display Guide (#644)
1 parent 2214d2e commit fae9946

File tree

18 files changed

+3364
-20
lines changed

18 files changed

+3364
-20
lines changed

.idea/AndroidProjectSystem.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. Take a look
1010

1111
#### Shared
1212

13+
* Implementation of the [W3C Accessibility Metadata Display Guide](https://w3c.github.io/publ-a11y/a11y-meta-display-guide/2.0/guidelines/) specification to facilitate displaying accessibility metadata to users. [See the dedicated user guide](docs/guides/accessibility.md).
1314
* Support for [W3C's Text & data mining Reservation Protocol](https://www.w3.org/community/reports/tdmrep/CG-FINAL-tdmrep-20240510/) in our metadata models.
1415
* Support for [accessibility exemption metadata](https://readium.org/webpub-manifest/contexts/default/#exemption), which allows content creators to identify publications that do not meet conformance requirements but fall under exemptions in a given juridiction.
1516
* Support for [EPUB Accessibility 1.1](https://www.w3.org/TR/epub-a11y-11/) conformance profiles.

Makefile

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ SCRIPTS_NAVIGATOR_WEB_PATH := readium/navigators/web/scripts
33

44
help:
55
@echo "Usage: make <target>\n\n\
6-
lint\t\tLint the Kotlin sources with ktlint\n\
7-
format\tFormat the Kotlin sources with ktlint\n\
8-
scripts\tBundle the Navigator EPUB scripts\n\
6+
lint\t\t\tLint the Kotlin sources with ktlint\n\
7+
format\t\tFormat the Kotlin sources with ktlint\n\
8+
scripts\t\tBundle the Navigator EPUB scripts\n\
9+
update-a11y-l10n\tUpdate the Accessibility Metadata Display Guide localization files\n\
910
"
1011

1112
.PHONY: lint
@@ -41,3 +42,11 @@ scripts-new:
4142

4243
.PHONY: scripts
4344
scripts: scripts-legacy scripts-new
45+
46+
.PHONY: update-a11y-l10n
47+
update-a11y-l10n:
48+
@which node >/dev/null 2>&1 || (echo "ERROR: node is required, please install it first"; exit 1)
49+
rm -rf publ-a11y-display-guide-localizations
50+
git clone https://github.com/w3c/publ-a11y-display-guide-localizations.git
51+
node scripts/convert-a11y-display-guide-localizations.js publ-a11y-display-guide-localizations android readium/shared/src/main readium_a11y_
52+
rm -rf publ-a11y-display-guide-localizations

docs/guides/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* [Extracting the content of a publication](content.md)
66
* [Supporting PDF documents](pdf.md)
77
* [Text-to-speech](tts.md)
8+
* [Accessibility](accessibility.md)
89
* [Supporting Readium LCP](lcp.md)
910
* [Navigator](navigator/navigator.md)
1011
* [Configuring the Navigator](navigator/preferences.md)

docs/guides/accessibility.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Accessibility
2+
3+
Some publications declare their accessibility features and limitations as metadata which broadly mirror the [EPUB Accessibility](https://www.w3.org/TR/epub-a11y-11) specification.
4+
5+
```kotlin
6+
val accessibility = publication.metadata.accessibility ?: Accessibility()
7+
8+
if (accessibility.accessModesSufficient.contains(setOf(PrimaryAccessMode.TEXTUAL))) {
9+
// This publication can be read aloud with a text-to-speech engine.
10+
}
11+
12+
if (accessibility.features.contains(Feature.DISPLAY_TRANSFORMABILITY)) {
13+
// The text and layout of this publication can be customized.
14+
}
15+
```
16+
17+
## Displaying accessibility metadata
18+
19+
While the [RWPM Accessibility models](https://readium.org/webpub-manifest/contexts/default/#accessibility-metadata) provide valuable information, they may be too complex and detailed to present to the user as it is. To simplify the presentation of this metadata to users, the Readium toolkit implements the [Accessibility Metadata Display Guide](https://w3c.github.io/publ-a11y/a11y-meta-display-guide/2.0/guidelines/) specification, developed by the W3C.
20+
21+
### How is the display guide structured?
22+
23+
The guide contains a list of fields that can be displayed as sections in your user interface. Each field has a list of related statements. For example, the `WaysOfReading` field provides information about whether the user can customize the text and layout (`visualAdjustments`) or if it is readable with text-to-speech or dynamic braille (`nonvisualReading`).
24+
25+
```kotlin
26+
val guide = AccessibilityMetadataDisplayGuide(publication)
27+
28+
when (guide.waysOfReading.visualAdjustments) {
29+
VisualAdjustments.MODIFIABLE -> {
30+
// The text and layout of the publication can be customized.
31+
}
32+
VisualAdjustments.UNMODIFIABLE -> {
33+
// The text and layout cannot be modified.
34+
}
35+
VisualAdjustments.UNKNOWN -> {
36+
// No metadata provided
37+
}
38+
}
39+
```
40+
41+
### Localized accessibility statements
42+
43+
While you are free to manually inspect the accessibility fields, the toolkit offers an API to automatically convert them into a list of localized statements (or claims) for direct display to the user.
44+
45+
Each statement has a *compact* and *descriptive* variant. The *descriptive* string is longer and provides more details about the claim.
46+
47+
For example:
48+
- **Compact**: Prerecorded audio clips
49+
- **Descriptive**: Prerecorded audio clips are embedded in the content
50+
51+
```kotlin
52+
for (statement in guide.waysOfReading.statements) {
53+
print(statement.localizedString(context, descriptive = false))
54+
}
55+
```
56+
57+
If translations are missing in your language, **you are encouraged to submit a contribution [to the official W3C repository](https://github.com/w3c/publ-a11y-display-guide-localizations)**.
58+
59+
### Displaying all the recommended fields
60+
61+
If you wish to display all the accessibility fields as recommended in the official specification, you can iterate over all the fields and their statements in the guide.
62+
63+
The `shouldDisplay` property indicates whether the field does not have any meaningful statement. In which case, you may skip it in your user interface.
64+
65+
```kotlin
66+
for (field in guide.fields) {
67+
if (!field.shouldDisplay) {
68+
continue
69+
}
70+
71+
print("Section: ${field.localizedTitle(context)}")
72+
73+
for (statement in field.statements) {
74+
print(statement.localizedString(context, descriptive = false))
75+
}
76+
}
77+
```
78+
79+
### Sample implementation in Jetpack Compose
80+
81+
```kotlin
82+
@Composable
83+
fun AccessibilityMetadata(guide: AccessibilityMetadataDisplayGuide, modifier: Modifier = Modifier) {
84+
val context = LocalContext.current
85+
var showDescriptiveStatements: Boolean by rememberSaveable { mutableStateOf(false) }
86+
87+
Column(
88+
modifier,
89+
verticalArrangement = Arrangement.spacedBy(16.dp)
90+
) {
91+
Text(
92+
text = "Accessibility Claims",
93+
style = MaterialTheme.typography.titleMedium
94+
)
95+
96+
Row(
97+
verticalAlignment = Alignment.CenterVertically,
98+
horizontalArrangement = Arrangement.SpaceBetween,
99+
modifier = modifier
100+
.fillMaxWidth()
101+
) {
102+
Text("Show descriptive statements")
103+
Switch(
104+
checked = showDescriptiveStatements,
105+
onCheckedChange = { showDescriptiveStatements = it }
106+
)
107+
}
108+
109+
for (field in guide.fields) {
110+
if (!field.shouldDisplay) {
111+
continue
112+
}
113+
114+
Text(
115+
text = field.localizedTitle(context),
116+
style = MaterialTheme.typography.labelMedium
117+
)
118+
119+
for (statement in field.statements) {
120+
Text(
121+
text = statement.localizedString(context, descriptive = showDescriptiveStatements),
122+
style = MaterialTheme.typography.bodyMedium
123+
)
124+
}
125+
}
126+
}
127+
}
128+
```

0 commit comments

Comments
 (0)