Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include more nbconvert and nbformat configuration options in the template #38

Merged
merged 14 commits into from
Feb 18, 2024
Merged
3 changes: 3 additions & 0 deletions nbconvert_a11y/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class A11yExporter(PostProcess, HTMLExporter):
).tag(config=True)
include_visibility = Bool(False, help="include visibility toggle").tag(config=True)
include_upload = Bool(False, help="include template for uploading new content").tag(config=True)
hide_anchor_links = Bool(False).tag(config=True)
exclude_anchor_links = Bool(True).tag(config=True)
code_theme = Enum(list(THEMES), "gh-high", help="an accessible pygments dark/light theme").tag(
config=True
Expand Down Expand Up @@ -153,6 +154,8 @@ 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["hide_anchor_links"] = self.hide_anchor_links
return resources

def from_notebook_node(self, nb, resources=None, **kw):
Expand Down
38 changes: 22 additions & 16 deletions nbconvert_a11y/templates/a11y/components/cell.html.j2
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
{% from "a11y/components/core.html.j2" import loc, hide %}
{% from "a11y/components/displays.html.j2" import cell_display_priority with context %}

{% macro cell_anchor(i, cell_type, hidden=False)%}
<a class="nb-anchor" href="#{{i}}" id="{{i}}" aria-labelledby="nb-cell-label {{i}}" {% if resources.accesskey_navigation
and isinstance(i, int) and (i < 10) %}accesskey="{{i}}" {% endif %}
aria-describedby="nb-{{cell_type}}-label nb-cell-label cell-{{i}}-loc nb-loc-label" {{hide(hidden)}}>{{i}}</a>
{% macro cell_anchor(i, cell_type, execution_count=None, outputs=None, hidden=False)%}
{% if not resources.exclude_anchors_links %}
<a class="nb-anchor{% if resources.hide_anchor_links%} visually-hidden{% endif %}" href="#{{i}}" id="{{i}}"
aria-labelledby="nb-cell-label {{i}}" {% if resources.accesskey_navigation and isinstance(i, int) and (i < 10)
%}accesskey="{{i}}" {% endif %} aria-describedby="nb-{{cell_type}}-label nb-cell-label {% if cell_type != "
markdown".strip() %}cell-{{i}}-loc nb-loc-label{% endif %}{% if cell_type==" code" .strip() and execution_count %}
cell-{{i}}-outputs-len{% endif %}" {{hide(hidden)}}>{{i}}</a>
{% endif %}
{% endmacro %}

{% macro cell_form(i, cell_type, hidden=True) %}
Expand All @@ -18,7 +22,7 @@ that would include talking to the kernel. #}
</form>
{% endmacro %}

{% macro cell_cell_type(i, cell_type, hidden=False) %}
{# {% macro cell_cell_type(i, cell_type, hidden=False) %}
{% set selected = ' selected id="cell-{}-cell_type"'.format(i) %}
<label class="nb-cell_type" id="nb-cell-{{i}}-select" {{hide(hidden)}}>cell type
<select name="cell_type" form="cell-{{i}}">
Expand All @@ -27,6 +31,10 @@ that would include talking to the kernel. #}
<option value="raw" {%- if cell_type=="raw" %}{{selected}}{% endif%}>raw</option>
</select>
</label>
{% endmacro %} #}

{% macro cell_cell_type(i, cell_type, hidden=False) %}
<label id="cell-{{i}}-cell_type" {{hide(hidden)}}>{{cell_type}}</label>
{% endmacro %}

{% macro cell_execution_count(i, execution_count, hidden=False) %}
Expand All @@ -43,7 +51,7 @@ that would include talking to the kernel. #}
<textarea class="nb-source" form="cell-{{i}}" id="cell-{{i}}-source" name="source"
rows="{{source.splitlines().__len__()}}" aria-labelledby="cell-{{i}}-source-label nb-source-label"
readonly>{{source}}</textarea>
<div role="group" aria-labelledby="nb-source-label">
<div role="group" aria-labelledby="nb-source-label" aria-roledescription="highlighted">
{{highlight(source, cell_type)}}
</div>
{% endmacro %}
Expand All @@ -64,28 +72,26 @@ that would include talking to the kernel. #}
{%- macro cell_output(i, cell, source, outputs, cell_type, execution_count, hidden=False) -%}
{% set CODE = cell_type == "code" %}
{% if CODE %}
{% if execution_count and not outputs %}
<span class="nb-outputs visually-hidden" id="cell-{{i}}-outputs-len">In {{execution_count}} has
{{outputs.__len__()}}
outputs.</span>
{% else %}
{% if execution_count %}
<span class="nb-outputs visually-hidden" id="cell-{{i}}-outputs-len">{{outputs.__len__()}} outputs.</span>
{% endif %}
{# the following span should get its own column in the table #}
<fieldset class="nb-outputs" {{hide(hidden)}} data-outputs="{{outputs.__len__()}}">
<legend id="cell-{{i}}-outputs-label" aria-describedby="nb-outputs-desc">
<fieldset
class="nb-outputs{% if cell.metadata.get('scrolled')%} nb-scrolled{% endif %}{% if cell.metadata.get('collapsed')%} nb-collapsed{% endif %}"
{{hide(hidden)}} data-outputs="{{outputs.__len__()}}">
<legend id="cell-{{i}}-outputs-label" aria-describedby="nb-outputs-desc" {{hide(not
resources.global_content_filter.include_output_prompt)}}>
<span>{{resources.prompt_out}}</span>
<span aria-hidden="true">{{resources.prompt_left}}</span>
<span>{{execution_count}}</span>
<span aria-hidden="true">{{resources.prompt_right}}</span>
</legend>
<span class="visually-hidden" id="cell-{{i}}-outputs-len">has {{outputs.__len__()}} output{% if outputs.__len__()>1
%}s{% endif %}</span>
{% if outputs %}
{# the output description should mention the number of outputs
saying zero outputs should be an option. a cell without an output is probably a violation. #}
{{cell_display_priority(i, outputs, cell)}}
{% endif %}
</fieldset>
{% endif %}
{% else %}
{{ markdown(source) | strip_files_prefix }}
{% endif %}
Expand Down
7 changes: 4 additions & 3 deletions nbconvert_a11y/templates/a11y/components/core.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ at some point effort should be put into separating context dependent and indepen
</label>
{% endmacro%}

{% macro checkbox(title, value)%}
{% macro checkbox(title, value, form=None)%}
{% set name="-".join(map(str.lower, title.split()))%}
<label><input type="checkbox" name="{{name}}" {%- if value %} checked{% endif %}>{{title}}</label>
<label><input type="checkbox" name="{{name}}" {%- if value %} checked{% endif %}{% if form %} form="{{form}}" {% endif
%}>{{title}}</label>
{% endmacro%}

{% macro dialog_close() %}
Expand Down Expand Up @@ -97,7 +98,7 @@ at some point effort should be put into separating context dependent and indepen
<label>{{title}}
<select name="{{name}}" id="{{name}}-select" multiple>
{% for k, v in values.items() %}
<option value="{{v}}" {% if k in default %} selected{% endif %}>{{k}}</option>
<option value="{{v}}" {% if k in default %} selected{% endif %} label="{{k}}">{{v}}</option>
{% endfor %}
</select>
</label>
Expand Down
6 changes: 4 additions & 2 deletions nbconvert_a11y/templates/a11y/components/settings.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ settings provides multiple screen reader navigation techniques when the dialog i

#}

{% from "a11y/components/core.html.j2" import h, radiogroup, select, activity_log, input_number, checkbox, dialog_close %}
{% from "a11y/components/core.html.j2" import h, radiogroup, select, activity_log, input_number, checkbox, dialog_close
%}
<dialog id="nb-settings">
<form name="settings">
{{h(1, "accessibility settings")}}
Expand All @@ -18,7 +19,8 @@ settings provides multiple screen reader navigation techniques when the dialog i
<li>{{select("cell navigation", values="list table landmark presentation".split(), disabled="grid
treegrid
tree".split())}}</li>
<li>{{select("accessibility priority", "AAA AA A".split(), resources.wcag_priority)}}</li>
{% set priority = {"Triple A": "AAA","Double A": "AA", "Single A": "A"}%}
<li>{{select("accessibility priority", priority, resources.wcag_priority)}}</li>
<li>{{checkbox("accesskey navigation", True)}}</li>
</ul>
</li>
Expand Down
4 changes: 3 additions & 1 deletion nbconvert_a11y/templates/a11y/components/visibility.html.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% from "a11y/components/core.html.j2" import activity_log %}
{% from "a11y/components/core.html.j2" import activity_log, checkbox %}

{% macro header_row(names) %}
<tr>
Expand Down Expand Up @@ -27,6 +27,8 @@
<dialog id="nb-visibility-dialog">
<form name="visibility">
<button formmethod="dialog">Close</button>
{{checkbox("visually hide", False)}}

<table aria-label="notebook cell visibility" role="grid">
<tbody>
{# the table head is used to provide controls #}
Expand Down
7 changes: 6 additions & 1 deletion nbconvert_a11y/templates/a11y/static/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ function setWCAG() {
);
}
document.forms.settings.elements["accessibility-priority"].addEventListener("change", setWCAG);
function toggleActive() {
function toggleActive() {
if (document.forms.notebook.elements.edit.checked) {
document.querySelectorAll("tr.cell>td>details>summary[inert]").forEach(
x => x.removeAttribute("inert")
Expand Down Expand Up @@ -192,6 +192,11 @@ function openDialogs() {
);
event.target.focus();
}
document.forms.visibility['visually-hide'].addEventListener("change",
(x) => {
document.querySelector("main").classList.toggle("visually-hide");
activityLog(`${event.target.checked ? "hiding" : "showing"} main content`);
});

setStyle("initialize saved settings.")
// async function runSource(target) {
Expand Down
17 changes: 14 additions & 3 deletions nbconvert_a11y/templates/a11y/static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ the variables specify critical degrees of freedom in the notebook style.
--nb-font-size: 16px;
--nb-font-family: serif;
--nb-line-height: 1.5;
--nb-scrolled-height: 600px;
}

/* map css variables to css properties on the `body` elements.
Expand Down Expand Up @@ -126,8 +127,8 @@ table {
}

main>.cell,
#cells .cell,
#cells > tbody {
#cells:not([role=table]) .cell,
#cells:not([role=table])>tbody {
display: flex;
flex-direction: column;
}
Expand Down Expand Up @@ -208,12 +209,22 @@ input[type="checkbox"] {
#nb-dialogs details:not([open])~dialog:not([open]):not(:focus-within):not(:active),
/* legend:not(:focus-within):not(:active), */
details.log:not([open])+table,
.visually-hidden:not(:focus-within):not(:active) {
.visually-hidden:not(:focus-within):not(:active),
.visually-hide {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}

.nb-outputs.nb-scrolled {
max-height: var(--nb-scrolled-height);
overflow: auto;
}

.nb-outputs.nb-collapsed {
display: none;
}
61 changes: 43 additions & 18 deletions nbconvert_a11y/templates/a11y/table.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,51 @@ cell_form, cell_source, cell_metadata, cell_output with context%}
{% set COLUMNS = ["index", "execution_count", "cell_type", "toolbar", "started_at", "completed_at", "source", "loc",
"metadata", "outputs"] %}

{% macro cell_row(cell, loop) %}
<tr role="listitem" class="cell {{cell.cell_type}}"
aria-labelledby="nb-cell-label {{loop.index}} cell-{{loop.index}}-cell_type"
data-loc="{{cell.source.splitlines().__len__()}}" {% if cell.cell_type=="code" %} {% endif %}
data-index="{{loop.index}}">
<td role="none" class="nb-anchor">{{cell_anchor(loop.index, cell.cell_type)}}</td>
<td role="none" class="nb-execution_count" {{hide(cell.cell_type=="markdown" or cell.execution_count==None)}}>
{{cell_execution_count(loop.index, cell.execution_count)}}
{% macro cell_row(cell, index) %}
{%- set include_outputs = True -%}
{%- set include_input = True -%}
{%- if cell.cell_type in ["raw"] -%}
{%- set include_input = resources.global_content_filter.include_raw and not (
cell.metadata.get("transient",{}).get("remove_source", false) or cell.metadata.get("jupyter",
{}).get("source_hidden", False))-%}
{%- elif cell.cell_type in ["markdown"]-%}
{%- set include_input = resources.global_content_filter.include_markdown and not (
cell.metadata.get("transient",{}).get("remove_source", false) or cell.metadata.get("jupyter",
{}).get("source_hidden", False)) -%}
{%- elif cell.cell_type in ["code"]-%}
{%- set include_input = resources.global_content_filter.include_code and not (not
resources.global_content_filter.include_input
or cell.metadata.get("jupyter", {}).get("source_hidden", False))
or cell.metadata.get("transient",{}).get("remove_source", false) -%}
{%- set include_outputs = cell.outputs and resources.global_content_filter.include_output
or not cell.metadata.get("jupyter", {}).get("outputs_hidden", False)-%}
{%- endif -%}
{%- set slide_type = cell.get("metadata", {}).get("slide_type") -%}
<tr role="listitem" class="cell {{cell.cell_type}}" aria-labelledby="nb-cell-label {{index}} cell-{{index}}-cell_type"
data-loc="{{cell.source.splitlines().__len__()}}" {% if cell.cell_type=="code" %} {% endif %} data-index="{{index}}"
{% if slide_type %} data-slide_type="{{slide_type}}" {% endif %}>
<td role="none" class="nb-anchor">{{cell_anchor(index, cell.cell_type, cell.execution_count, cell.outputs)}}</td>
<td role="none" class="nb-execution_count" {{hide(cell.cell_type=="markdown" or cell.execution_count==None or not
resources.global_content_filter.include_input_prompt)}}>
{{cell_execution_count(index, cell.execution_count)}}
</td>
<td role="none" class="nb-cell_type" hidden>{{cell_cell_type(loop.index, cell.cell_type)}}</td>
<td role="none" class="nb-toolbar" hidden>{{cell_form(loop.index)}}</td>
<td role="none" class="nb-start" id="cell-{{loop.index}}-start" hidden>
<td role="none" class="nb-cell_type" hidden>{{cell_cell_type(index, cell.cell_type)}}</td>
<td role="none" class="nb-toolbar" hidden>{{cell_form(index)}}</td>
<td role="none" class="nb-start" id="cell-{{index}}-start" hidden>
{% set t0 = cell.get("metadata", {}).get("execution", {}).get("iopub.execute_input", "") %}
{{time(t0)}}</td>
<td role="none" class="nb-end" id="cell-{{loop.index}}-end" hidden>
<td role="none" class="nb-end" id="cell-{{index}}-end" hidden>
{% set t1 = cell.get("metadata", {}).get("execution", {}).get("shell.execute_reply", "") %}
{{time(t1)}}
</td>
<td role="none" class="nb-source" {{hide(cell.cell_type=="markdown" )}}>{{cell_source(loop.index,
<td role="none" class="nb-source" {{hide(cell.cell_type=="markdown" or not include_input)}}>{{cell_source(index,
cell.source, cell.cell_type, cell.execution_count)}}</td>
<td role="none" class="nb-metadata" hidden>{{cell_metadata(loop.index, cell.get("metadata", {}))}}</td>
<td role="none" class="nb-metadata" hidden>{{cell_metadata(index, cell.get("metadata", {}))}}</td>
{# it was noted in a video that lines of code were helpful in assistive descriptions.
lines of code are part of the gestalt of code forms. #}
<td role="none" class="nb-loc" id="cell-{{loop.index}}-loc" hidden>{{loc(cell)}}</td>
<td role="none" class="nb-outputs">{{cell_output(loop.index, cell, cell.source, cell.outputs,
<td role="none" class="nb-loc" id="cell-{{index}}-loc" hidden>{{loc(cell)}}</td>
<td role="none" class="nb-outputs" {{hide(not include_outputs)}}>{{cell_output(index, cell, cell.source,
cell.outputs,
cell.cell_type,
cell.execution_count)}}</td>
</tr>
Expand All @@ -38,6 +58,11 @@ cell_form, cell_source, cell_metadata, cell_output with context%}
{% block body_loop %}
{# the most consistent implementation would connect the input visibility to a form #}
<table id="cells" role="presentation">
<colgroup>
{% for col in COLUMNS %}
<col class="nb-{{col}}">
{% endfor %}
</colgroup>
<tbody role="list" aria-labelledby="nb-notebook-label nb-cells-label">
<tr hidden>
{% for col in COLUMNS %}
Expand All @@ -46,7 +71,7 @@ cell_form, cell_source, cell_metadata, cell_output with context%}
</tr>
{%- for cell in nb.cells -%}
{% block any_cell scoped %}
{{cell_row(cell, loop)}}
{{cell_row(cell, loop.index)}}
{% endblock any_cell %}
{%- endfor -%}
</tbody>
Expand Down Expand Up @@ -93,7 +118,7 @@ cell_form, cell_source, cell_metadata, cell_output with context%}
</table>
{% endblock body_loop %}

{# adding a template element is a forward thinking move because
{# adding a template element is a forward thinking move because
the template provides the structure for new cells when they are added. #}
{% block template_element %}
<template>
Expand Down
Loading