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

the cell is landmark for a form #63

Merged
merged 36 commits into from
Jun 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
7aef293
add new accessible patterns
tonyfast May 13, 2023
f9413fa
add templates for multiple conformations of notebooks
tonyfast May 13, 2023
8a11b2d
add more configurations to test the extent
tonyfast May 13, 2023
8548eef
make template file configurable
tonyfast May 13, 2023
5ea6c41
cleaner sections template
tonyfast May 26, 2023
bb0e798
add cell tempalte
tonyfast May 26, 2023
2e1151e
add labels
tonyfast May 27, 2023
83306a9
more accessibility revisions
tonyfast May 31, 2023
23feb32
fix skip link class. separate cell and for. adapt css.
tonyfast May 31, 2023
27b4490
rm aria hidden opinion
tonyfast May 31, 2023
58a67be
remove screen reader verbosity
tonyfast May 31, 2023
e896f77
expose pygments to the template
tonyfast May 31, 2023
48c8775
add light dark support
tonyfast May 31, 2023
58d9f4e
add width to output
tonyfast May 31, 2023
18f8e31
add presentation role markdown input fieldset and all output fieldsets
tonyfast Jun 2, 2023
3a453ca
add the smol variant as the minimum interface
tonyfast Jun 3, 2023
63a5993
this feels pretty dialed now
tonyfast Jun 4, 2023
a339e89
add label to the textarea
tonyfast Jun 4, 2023
8e74b64
label the textarea input, cell and output
tonyfast Jun 4, 2023
3f8998b
legend is the label for the textarea, the visual input label is aria …
tonyfast Jun 4, 2023
488c696
remove comments from smol
tonyfast Jun 4, 2023
347d254
reduce the role of the output fieldset in markdown cells
tonyfast Jun 5, 2023
fd5563d
move toolbar up and hide form
tonyfast Jun 5, 2023
1b6322a
move form outside the section so that it the action can be used as a …
tonyfast Jun 5, 2023
12c2b9f
include a title
tonyfast Jun 5, 2023
a1a064b
move markdown cell output outside the fielset group to increase the l…
tonyfast Jun 5, 2023
2689ea1
remove labels from the display outputs. this is future work
tonyfast Jun 5, 2023
9d59ed8
hidden legend for markdown outputs
tonyfast Jun 5, 2023
90d09e6
add overflow to the output fieldset instead of the cell
tonyfast Jun 6, 2023
7f44506
visually hide output legend and aria hide label
tonyfast Jun 6, 2023
ef0c8dd
label form
tonyfast Jun 6, 2023
e9565a8
hide label with markdown
tonyfast Jun 6, 2023
cf38b79
css suppresses markdown output label instead. this is a visual mistak…
tonyfast Jun 6, 2023
59495d4
out announcements got lost on voiceover, try different display mechanism
tonyfast Jun 5, 2023
32ec0aa
add visual label for cell numbers
tonyfast Jun 7, 2023
4e40ecb
hide cell numbers again
tonyfast Jun 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion nbconvert_html5/form_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import builtins
import bs4
import pygments
from traitlets import Unicode
import nbconvert_html5
import pydantic
import nbformat.v4
Expand Down Expand Up @@ -289,7 +290,7 @@ def post_process_code_cell(self, cell):
pass
A/B testing with out requiring `nbconvert` or notebook knowleldge."""

template_file = "semantic-forms/table.html.j2"
template_file = Unicode("semantic-forms/table.html.j2").tag(config=True)
exclude_anchor_links = True

def __init__(self, *args, **kwargs):
Expand All @@ -306,6 +307,7 @@ def __init__(self, *args, **kwargs):
import html
self.environment.globals.update(json=json, markdown=markdown)
self.environment.filters.update(escape_html=html.escape)
self.environment.globals.update(formatter=pygments.formatters)


def from_notebook_node(self, nb, resources=None, **kw):
Expand Down
60 changes: 54 additions & 6 deletions nbconvert_html5/templates/semantic-forms/base.html.j2
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
{%- extends 'display_priority.j2' -%}
{% from 'celltags.j2' import celltags %}

{% block output %}
<output form="{{ID}}" for="{{ID}}-source" role="document" class="output_area">
{{ super() }}
</output>
{% endblock output %}

{% block execute_result -%}
{%- set extra_class="output_execute_result" -%}
{% block data_priority scoped %}
Expand Down Expand Up @@ -178,3 +172,57 @@ var element = $('#{{ div_id }}');
{%- endif %}
{{ super() }}
{%- endblock footer-%}



{% macro cell_form(cell, nb) %}
{% set count = nb["cells"].index(cell) +1%}
{% set ID = "/cells/" + str(cell.id or count) %}
<form id="{{ID}}" aria-label="Cell Source {{count}}">
{{cell_type_cell(cell)}}
<label>
<textarea name="source" id="{{ID}}/source" readonly>{{cell.source}}</textarea>
</label>
</form>
{{cell_toolbar(cell, ID)}}
<output class="render" for="{{ID}}/source" form={{ID}} aria-hidden="{% if cell.cell_type == "markdown" %}false{% else %}true{% endif %}">
{% if cell.cell_type=="markdown" %}{{markdown(cell.source) | strip_files_prefix}}{% endif %}
{% if cell.cell_type=="code" %}{{ cell.source | highlight_code(metadata=cell.metadata) }}{% endif %}
</output>
<output form={{ID}} for="{{ID}}/source" name=execution_count id="{{ID}}/outputs">{{cell.execution_count or ""}}</output>
<output form={{ID}} for="{{ID}}/source" name=outputs role=log>{{outputs_cell(cell, ID)}}</output>
{% endmacro%}

{% macro cell_type_cell(cell) %}
{% set cell_type = cell.cell_type %}
<label class="cell_type">
<select name="cell_type" disabled>
<option {% if cell_type=="code" %}selected{% endif %} value="code">code</option>
<option {% if cell_type=="markdown" %}selected{% endif %} value="markdown">markdown</option>
<option {% if cell_type=="raw" %}selected{% endif %} value="raw">raw</option>
<option {% if cell_type=="unknown" %}selected{% endif %} value="unknown">unknown</option>
</select>
</label>
{% endmacro %}

{% macro outputs_cell(cell, ID) %}
{% for i, output in enumerate(cell.outputs) %}
{% block output scoped %}{% block output_prompt %}{% endblock %}{{super()}}{% endblock %}
{% endfor %}
{% endmacro %}


{% macro cell_toolbar(cell, ID) %}
<menu class="cell toolbar" hidden>
<input class="run" type="submit" form="{{ID}}" for="{{ID}}-source" value="run" title="run the cell"
tabindex="0">
<button onclick="document.querySelector('#{{ID}}-metadata').showModal()" title="show metadata">🛈</button>
</menu>
{% endmacro %}

{% macro hide(x) %}{% if not x %}hidden{% endif %}{% endmacro %}


{% macro highlight(body, type) %}
{{markdown("```{{type}}\n" + json.dumps(nb.metadata, indent=2) + "\n```\n")}}
{% endmacro %}
105 changes: 105 additions & 0 deletions nbconvert_html5/templates/semantic-forms/cell.html.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{%- extends 'semantic-forms/index.html.j2' -%}

{# cell is a tough analogy, it is an ambiguous signifier dependent on context.
the analogy to a biologic cell asks "what is the nucleus?" or "what encodes the objective?".
the source input feels like it is the irreducible element of our computational cells.
lines of text evolve over time. like dna they replicate, mutate, evolve, and cooperate.

allied alphabets dancing on carefully organized sand emitting waves of sound, light, and hope.
the lines in the source, the nucleus, freeze a sliver of a movement in hypermedia.

#}
{%- macro cell_textarea(cell, nb) -%}
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
<label for="{{ID}}/source">{# https://www.w3.org/WAI/WCAG21/Techniques/general/G208 #}
<textarea name="source" id="{{ID}}/source" form="{{ID}}" readonly>{{cell.source}}</textarea>
</label>
{%- endmacro -%}


{%- macro cell_forms(cell, nb, body) -%}
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
<form id="{{ID}}" name="{{ID}}" method="POST" aria-labelledby="{{ID}}/execution_count">
{{body}}
</form>
{%- endmacro -%}


{%- macro cell_form_element(cell, nb) -%}
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
<form id="{{ID}}" name="{{ID}}" method="POST"></form>
{%- endmacro -%}

{%- macro cell_submit(cell, nb) -%}
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
{# https://www.w3.org/TR/WCAG20-TECHS/H32.html #}
<button form="{{ID}}" type="submit" disabled aria-label="Run Cell"></button>
{%- endmacro -%}

{%- macro cell_toolbars(cell, nb, body) -%}
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
<ul role="toolbar" aria-labelledby="{{ID}}/execution_count">{%- for part in body -%}<li>{{part}}</li>{%- endfor -%}</ul>
{%- endmacro -%}

{%- macro cell_type(cell, nb) -%}
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
{%- set cell_type = cell.cell_type -%}
<select name="cell_type" aria-label="Cell Type" form="{{ID}}" disabled>
<option {% if cell_type=="code" %}selected{% endif %} value="code">code</option>
<option {% if cell_type=="markdown" %}selected{% endif %} value="markdown">markdown</option>
<option {% if cell_type=="raw" %}selected{% endif %} value="raw">raw</option>
<option {% if cell_type=="unknown" %}selected{% endif %} value="unknown">unknown</option>
</select>
{%- endmacro -%}

{# the execution count has been one of the most confusing aspects of this journey.
it's meaning wasn't revealed until the very end of this rigorous study.
the result discovered labelable, interactive elements that describe the components of the cell.
assistive technology requires labels for interactive objects and the semantic representation allows the re-use
of the execution count label on different elements with different roles.
#}
{%- macro cell_execution_count_out(cell, nb, body) -%}
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
{% if cell.cell_type == "code" %}
<label for="{{ID}}/source" name=execution_count id="{{ID}}/execution_count">Out: {{cell.execution_count or ""}}</label>
{% else %}
<label for="{{ID}}/source" name=execution_count id="{{ID}}/execution_count">Cell {{count}}</label>
{% endif %}
{%- endmacro -%}

{%- macro cell_execution_count_in(cell, nb, body) -%}
tonyfast marked this conversation as resolved.
Show resolved Hide resolved
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
{% if cell.cell_type == "code" %}
<label for="{{ID}}/source" name=execution_count id="{{ID}}/execution_count">In: {{cell.execution_count or ""}}</label>
{% else %}
<label for="{{ID}}/source" name=execution_count id="{{ID}}/execution_count">Cell {{count}}</label>
{% endif %}
{%- endmacro -%}

{%- macro cell_outputs(cell, nb, parts) -%}
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
<fieldset name="outputs" id="{{ID}}/outputs" role="presentation" {%- if not cell.outputs %}hidden{% endif %}>
<legend>{{ cell_execution_count_out(cell, nb) }}</legend>
{{cell_display_priority(cell, ID)}}
</fieldset>
{%- endmacro -%}

{%- macro cell_render(cell, nb, parts) -%}
{%- set count = nb["cells"].index(cell)-%}{%- set ID = "/cells/" + str(count) -%}
{% set CODE = cell.cell_type=="code" %}
<output role="presentation" class="render" form={{ID}} aria-labelledby="{{ID}}/execution_count">
{%- if CODE -%}{{ cell.source | highlight_code(metadata=cell.metadata) }}{% else %}{{markdown(cell.source) |
strip_files_prefix}}{%- endif -%}
</output>
{%- endmacro -%}

{%- macro cell_display_priority(cell, ID) -%}
{%- for i, output in enumerate(cell.outputs) -%}
{%- block output scoped -%}{%- block output_prompt -%}{%- endblock-%}{{super()}}{%- endblock -%}
{%- endfor -%}
{%- endmacro -%}


{%- macro highlight(body, type) -%}
{{markdown("```{{type}}\n" + json.dumps(nb.metadata, indent=2) + "\n```\n")}}
{%- endmacro -%}
13 changes: 13 additions & 0 deletions nbconvert_html5/templates/semantic-forms/feed.html.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{%- extends 'semantic-forms/index.html.j2' -%}
{% from 'mathjax.html.j2' import mathjax %}
{% from 'jupyter_widgets.html.j2' import jupyter_widgets %}

{% block body_loop %}
<section role="feed">{{super()}}</section>
{% endblock body_loop %}

{% block any_cell %}
<article class="cell {{cell.cell_type}} {{celltags(cell)}}">
{{cell_form(cell, nb)}}
</article>
{% endblock any_cell %}
61 changes: 61 additions & 0 deletions nbconvert_html5/templates/semantic-forms/forms.html.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{%- extends 'semantic-forms/index.html.j2' -%}
{% from 'mathjax.html.j2' import mathjax %}
{% from 'jupyter_widgets.html.j2' import jupyter_widgets %}


{% block any_cell %}
{{cell_section(cell, nb, resources)}}
{% endblock any_cell %}

{% macro highlight(body, type) %}
{{markdown("```{{type}}\n" + json.dumps(nb.metadata, indent=2) + "\n```\n")}}
{% endmacro %}


{% macro cell_section(cell, nb, resources={}) %}
{% set count = nb.cells.index(cell) %}
{% set ID = "/cells/" + str(cell.id or count) %}
<form id="{{ID}}">
{{cell_type_cell(cell)}}
<label>
<textarea name="source" id="{{ID}}/source">{{cell.source}}</textarea>
</label>
</form>
{{cell_toolbar(cell, ID)}}
<output class="render" for="{{ID}}/source" form={{ID}} aria-hidden="{% if cell.cell_type == "markdown" %}false{% else %}true{% endif %}">
{% if cell.cell_type=="markdown" %}{{markdown(cell.source) | strip_files_prefix}}{% endif %}
{% if cell.cell_type=="code" %}{{ cell.source | highlight_code(metadata=cell.metadata) }}{% endif %}
</output>
<output form={{ID}} for="{{ID}}/source" name=execution_count id="{{ID}}/outputs">{{cell.execution_count or ""}}</output>
<output form={{ID}} for="{{ID}}/source" name=outputs role=log>{{outputs_cell(cell, ID)}}</output>
{% endmacro %}


{% macro cell_type_cell(cell) %}
{% set cell_type = cell.cell_type %}
<label class="cell_type">
<select name="cell_type" disabled>
<option {% if cell_type=="code" %}selected{% endif %} value="code">code</option>
<option {% if cell_type=="markdown" %}selected{% endif %} value="markdown">markdown</option>
<option {% if cell_type=="raw" %}selected{% endif %} value="raw">raw</option>
<option {% if cell_type=="unknown" %}selected{% endif %} value="unknown">unknown</option>
</select>
</label>
{% endmacro %}

{% macro outputs_cell(cell, ID) %}
{% for i, output in enumerate(cell.outputs) %}
{% block output scoped %}{% block output_prompt %}{% endblock %}{{super()}}{% endblock %}
{% endfor %}
{% endmacro %}


{% macro cell_toolbar(cell, ID) %}
<menu class="cell toolbar">
<input class="run" type="submit" form="{{ID}}" for="{{ID}}-source" value="run" title="run the cell"
tabindex="0">
<button onclick="document.querySelector('#{{ID}}-metadata').showModal()" title="show metadata">🛈</button>
</menu>
{% endmacro %}

{% macro hide(x) %}{% if not x %}hidden{% endif %}{% endmacro %}
41 changes: 41 additions & 0 deletions nbconvert_html5/templates/semantic-forms/index.html.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{%- extends 'semantic-forms/base.html.j2' -%}
{% from 'mathjax.html.j2' import mathjax %}
{% from 'jupyter_widgets.html.j2' import jupyter_widgets %}

{%- block header -%}
<!DOCTYPE html>
<html lang="en">
<head>
{%- block html_head -%}
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% set nb_title = nb.metadata.get('title', resources['metadata']['name']) | escape_html_keep_quotes %}
<title>{{nb_title}}</title>
{% block css %}{% endblock css %}
{%- endblock html_head -%}
</head>
{%- endblock -%}


{% block body_header %}
<body>
<header class="site">
{% block skip_links %}<a class="visually-hidden" tabindex="0" href="#/">Skip to content</a>{% endblock skip_links %}
</header>
<main id="/">
{% endblock body_header %}


{% block body_footer %}
</main>
<footer><a class="scroll-top" href="#/">Scroll to top.</a></footer>
</body>
{% endblock body_footer %}

{% block footer %}
{% block footer_js %}
{% endblock footer_js %}
{{ super() }}
</html>
{% endblock footer %}

13 changes: 13 additions & 0 deletions nbconvert_html5/templates/semantic-forms/ol.html.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{%- extends 'semantic-forms/index.html.j2' -%}
{% from 'mathjax.html.j2' import mathjax %}
{% from 'jupyter_widgets.html.j2' import jupyter_widgets %}

{% block body_loop %}
<ol>{{super()}}</ol>
{% endblock body_loop %}

{% block any_cell %}
<li class="cell {{cell.cell_type}} {{celltags(cell)}}">
{{cell_form(cell, nb)}}
</li>
{% endblock any_cell %}
Loading