Skip to content

Commit

Permalink
add semantically meaningful outputs to the project (#44)
Browse files Browse the repository at this point in the history
* start adding semantic reprs for python object

* styling and dataframe fixes

* use nbconvert markdown to get image embedding

* add numpy types

* add ability to toggle reprs

* change name for hidden anchor links

* add focus on visually hidden output

* fix settings impl

* priority aa style for pygments line height

* use esm for sa11y

* rm errant variable

* sa11y toggle

* add the execution state the cell

* introduce kernel information to the notebook summary

* update sa11y reps
  • Loading branch information
tonyfast authored Mar 26, 2024
1 parent 1c7b051 commit d9cec77
Show file tree
Hide file tree
Showing 12 changed files with 726 additions and 63 deletions.
30 changes: 21 additions & 9 deletions nbconvert_a11y/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""

import builtins
from copy import copy, deepcopy
import json
from contextlib import suppress
from datetime import datetime
Expand Down Expand Up @@ -73,7 +74,7 @@ class Table:
}


class PostProcess(Exporter):
class PostProcess(HTMLExporter):
"""an exporter that allows post processing after the templating step
this class introduces the `post_process_html` protocol that can be used to modify
Expand All @@ -88,7 +89,7 @@ def from_notebook_node(self, nb, resources=None, **kw):
def post_process_html(self, body): ...


class A11yExporter(PostProcess, HTMLExporter):
class A11yExporter(PostProcess):
"""an accessible reference implementation for computational notebooks implemented for ipynb files.
this template provides a flexible screen reader experience with settings to control and customize the reading experience.
Expand All @@ -99,7 +100,7 @@ class A11yExporter(PostProcess, HTMLExporter):
config=True
)
axe_url = CUnicode(AXE, help="the remote source for the axe resources.").tag(config=True)
include_sa11y = Bool(False, help="include sa11y accessibility authoring tool").tag(config=True)
include_sa11y = Bool(True, help="include sa11y accessibility authoring tool").tag(config=True)
include_settings = Bool(False, help="include configurable accessibility settings dialog.").tag(
config=True
)
Expand All @@ -126,7 +127,7 @@ class A11yExporter(PostProcess, HTMLExporter):
include_upload = Bool(False, help="include template for uploading new content").tag(config=True)
allow_run_mode = Bool(False, help="enable buttons for a run mode").tag(config=True)
hide_anchor_links = Bool(False).tag(config=True)
exclude_anchor_links = Bool(False).tag(config=True)
hidden_anchor_links = Bool(False).tag(config=True)
code_theme = Enum(list(THEMES), "gh-high", help="an accessible pygments dark/light theme").tag(
config=True
)
Expand All @@ -140,6 +141,7 @@ class A11yExporter(PostProcess, HTMLExporter):
prompt_out = CUnicode("Out").tag(config=True)
prompt_left = CUnicode("[").tag(config=True)
prompt_right = CUnicode("]").tag(config=True)
validate_nb = Bool(False).tag(config=True)

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -177,9 +179,7 @@ def default_config(self):
return c

def init_resources(self, resources=None):
if resources is None:
resources = {}
resources = resources or {}
resources = self._init_resources(resources)
resources["include_axe"] = self.include_axe
resources["include_settings"] = self.include_settings
resources["include_help"] = self.include_help
Expand All @@ -196,7 +196,7 @@ def init_resources(self, resources=None):
resources["prompt_out"] = self.prompt_out
resources["prompt_left"] = self.prompt_left
resources["prompt_right"] = self.prompt_right
resources["exclude_anchor_links"] = self.exclude_anchor_links
resources["hidden_anchor_links"] = self.hidden_anchor_links
resources["hide_anchor_links"] = self.hide_anchor_links
resources["table_pattern"] = getattr(Roles, self.table_pattern)
resources["allow_run_mode"] = self.allow_run_mode
Expand All @@ -218,6 +218,18 @@ def post_process_html(self, body):
details.append(toc(soup))
return soup.prettify(formatter="html5")

def _preprocess(self, nb, resources):
nbc = deepcopy(nb)
resc = deepcopy(resources)

for preprocessor in self._preprocessors:
nbc, resc = preprocessor(nbc, resc)

if self.validate_nb:
self._validate_preprocessor(nbc, preprocessor)

return nbc, resc


class SectionExporter(A11yExporter):
template_file = Unicode("a11y/section.html.j2").tag(config=True)
Expand Down Expand Up @@ -303,7 +315,7 @@ def toc(html):
level = int(header.name[-1])
if last_level > level:
for l in range(level, last_level):
last_level -= 1
last_level -= 1
ol = ol.parent.parent
elif last_level < level:
for l in range(last_level, level):
Expand Down
164 changes: 164 additions & 0 deletions nbconvert_a11y/outputs.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/* css to accompany the semantic outputs.py
these styles make the semantic html appear like python styled reprs.
prettifying python combines content and style, but with html
we can seperate these concerns. */

:root {
--quote: '"';
}

data[value],
[itemscope]:not([itemtype$=DataFrame]),
[itemscope]:not([itemtype$=Series]) {
font-family: monospace;
}

.jp-RenderedHTMLCommon kbd {
font-size: unset;
}

samp[itemscope]::before,
samp[itemscope]::after {
content: var(--quote);
}

.jp-RenderedHTMLCommon [itemscope] {
color: var(--jp-mirror-editor-number-color);
}

.jp-RenderedHTMLCommon data[value] {
color: var(--jp-mirror-editor-keyword-color);
font-weight: bold;
}

.jp-RenderedHTMLCommon samp[itemscope] {
color: var(--jp-mirror-editor-string-color);
}

ol[itemscope],
ul[itemscope] {
li {
display: inline;

&::after {
content: ", ";
}

&:first-child::before {
content: '[';
color: var(--jp-mirror-editor-bracket-color);
}

&:last-child::after {
content: ']';
color: var(--jp-mirror-editor-bracket-color);
}
}
}

ol[itemtype$=tuple] li {
&:first-child::before {
content: '(';
}

&:last-child::after {
content: ')';
}
}

ul[itemtype$=set] li {
&:first-child::before {
content: '{';
}

&:last-child::after {
content: '}';
}
}

.jp-OutputArea-output table caption,
table caption {

dl,
dd,
dt {
padding-left: .5em;
padding-right: .5em;
}

}


.jp-OutputArea-output dd,
.jp-OutputArea-output dt {
float: unset;
display: unset;
}

dl[itemscope] dd,
dl[itemscope] dt {
display: inline;
}

dl[itemtype] {

dt:first-child::before {
content: "{";
color: var(--jp-mirror-editor-bracket-color);
}
dd:last-child::after {
content: "}";
color: var(--jp-mirror-editor-bracket-color);
}
dt::after {
content: ": ";
}
dd::after {
content: ", ";
}
}
.visually-hidden:not(:active):not(:focus-within),
.non-visual,
.nv {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
table[itemtype$=ndarray] {
text-align: right;
td:first-child::before {
content: "[";
float: left;
}
td::after {
content: ",";
}
td:last-child::after {
content: "]";
}
}

:not(.jp-RenderedMarkdown).jp-RenderedHTMLCommon td,
:not(.jp-RenderedMarkdown).jp-RenderedHTMLCommon th,
:not(.jp-RenderedMarkdown).jp-RenderedHTMLCommon tr {
vertical-align: unset;
text-align: unset;
}

.jp-RenderedHTMLCommon tr {
padding: unset;
}
Loading

0 comments on commit d9cec77

Please sign in to comment.