From 7aef2936ae483628af94f7312aee9c96eded2d4e Mon Sep 17 00:00:00 2001 From: tonyfast Date: Fri, 12 May 2023 17:59:34 -0700 Subject: [PATCH 01/36] add new accessible patterns --- .../templates/semantic-forms/base.html.j2 | 60 +++++- .../templates/semantic-forms/feed.html.j2 | 13 ++ .../templates/semantic-forms/static/script.js | 2 +- .../templates/semantic-forms/static/style.css | 42 ++--- .../templates/semantic-forms/table.html.j2 | 172 +++++------------- pyproject.toml | 11 +- 6 files changed, 135 insertions(+), 165 deletions(-) create mode 100644 nbconvert_html5/templates/semantic-forms/feed.html.j2 diff --git a/nbconvert_html5/templates/semantic-forms/base.html.j2 b/nbconvert_html5/templates/semantic-forms/base.html.j2 index 35973bb6..59a540f6 100644 --- a/nbconvert_html5/templates/semantic-forms/base.html.j2 +++ b/nbconvert_html5/templates/semantic-forms/base.html.j2 @@ -1,12 +1,6 @@ {%- extends 'display_priority.j2' -%} {% from 'celltags.j2' import celltags %} -{% block output %} - -{{ super() }} - -{% endblock output %} - {% block execute_result -%} {%- set extra_class="output_execute_result" -%} {% block data_priority scoped %} @@ -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) %} +
+ {{cell_type_cell(cell)}} + +
+{{cell_toolbar(cell, ID)}} + + {% 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 %} + +{{cell.execution_count or ""}} +{{outputs_cell(cell, ID)}} +{% endmacro%} + +{% macro cell_type_cell(cell) %} +{% set cell_type = cell.cell_type %} + +{% 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) %} + +{% 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 %} \ No newline at end of file diff --git a/nbconvert_html5/templates/semantic-forms/feed.html.j2 b/nbconvert_html5/templates/semantic-forms/feed.html.j2 new file mode 100644 index 00000000..207282f9 --- /dev/null +++ b/nbconvert_html5/templates/semantic-forms/feed.html.j2 @@ -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 %} +
{{super()}}
+{% endblock body_loop %} + +{% block any_cell %} +
+{{cell_form(cell, nb)}} +
+{% endblock any_cell %} \ No newline at end of file diff --git a/nbconvert_html5/templates/semantic-forms/static/script.js b/nbconvert_html5/templates/semantic-forms/static/script.js index a05fe389..23a95e65 100644 --- a/nbconvert_html5/templates/semantic-forms/static/script.js +++ b/nbconvert_html5/templates/semantic-forms/static/script.js @@ -114,12 +114,12 @@ window.addEventListener('load', function () { slider.addEventListener("input", (event) => { var id = `#/cells/${event.target.value}`; event.target.nextElementSibling.value = event.target.value; - document.getElementById(id.substring(1)).scrollIntoView(); }); // the cell slider updates the page history slider.addEventListener("change", (event) => { var id = `#/cells/${event.target.value}`; + document.getElementById(id.substring(1)).scrollIntoView(); history.replaceState({}, `Cell ${event.target.value}`, id); }) diff --git a/nbconvert_html5/templates/semantic-forms/static/style.css b/nbconvert_html5/templates/semantic-forms/static/style.css index 39bc9e0a..d5f17be9 100644 --- a/nbconvert_html5/templates/semantic-forms/static/style.css +++ b/nbconvert_html5/templates/semantic-forms/static/style.css @@ -40,28 +40,25 @@ main>header details.nav { main>header { overflow: auto; opacity: .9; - position: sticky; - top: 0; - max-height: 100vh; } -main > table.cells > thead { +main > .cells > thead { display: none; } -.static td.execution_count label:not(:empty):before { +.static .execution_count label:not(:empty):before { content: "In: "; } -table.cells { +.cells { width: 100%; } -tr.cell { +.cell { display: grid; } -tr.code.cell { +.code.cell { grid-template-rows: 2rem 1rem auto auto; grid-template-columns: 5fr 95fr; justify-items: start; @@ -71,22 +68,22 @@ tr.code.cell { width: 95vw; } -tr.markdown.cell { +.markdown.cell { grid-template-columns: 95fr 5fr; grid-template-areas: "source toolbar"; } -tr.cell>td.source { +textarea.source { grid-area: source; width: 100%; overflow-x: auto; } -tr.cell>td.cell_type { +.cell>.cell_type { grid-area: cell_type; } -tr.cell>td.outputs { +.cell>.outputs { overflow-x: auto; grid-area: outputs; display: flex; @@ -94,28 +91,29 @@ tr.cell>td.outputs { width: 100%; } -tr.cell>td.toolbar { +.cell>.toolbar { grid-area: toolbar; } -tr.cell>td.execution_count { +.cell>.execution_count { grid-area: execution_count; } -td.source form textarea { +textarea.source { width: 100%; } -td.cell_type, -tr.cell form label.cell_type, -tr.markdown.cell td.outputs, -tr.markdown.cell td.execution_count, -.static td.toolbar, +.cell_type, +.cell label.cell_type, +.markdown.cell .outputs, +.markdown.cell .execution_count, +.static .toolbar, .static input.run, -.static tr.markdown.cell td.source form textarea { +.static .markdown.cell textarea.source, +.markdown fieldset.outputs { display: none; } -td.source form textarea:focus~.render { +.cell textarea.source:focus~.render { display: none; } \ No newline at end of file diff --git a/nbconvert_html5/templates/semantic-forms/table.html.j2 b/nbconvert_html5/templates/semantic-forms/table.html.j2 index f90c3c6c..3cd9d1fb 100644 --- a/nbconvert_html5/templates/semantic-forms/table.html.j2 +++ b/nbconvert_html5/templates/semantic-forms/table.html.j2 @@ -1,136 +1,46 @@ -{%- extends 'semantic-forms/base.html.j2' -%} +{%- extends 'semantic-forms/index.html.j2' -%} {% from 'mathjax.html.j2' import mathjax %} {% from 'jupyter_widgets.html.j2' import jupyter_widgets %} -{%- block header -%} - - - - {%- block html_head -%} - - - {% set nb_title = nb.metadata.get('title', resources['metadata']['name']) | escape_html %} - {{nb_title}} - - - - - {% block jupyter_widgets %} - {%- if "widgets" in nb.metadata -%} - - {{ jupyter_widgets(resources.jupyter_widgets_base_url, resources.html_manager_semver_range, - resources.widget_renderer_url) }} - {%- endif -%} - {% endblock jupyter_widgets %} - - {% block extra_css %} - {% endblock extra_css %} - - {% for css in resources.inlining.css -%} - - {% endfor %} - - {% block notebook_css %} - {{ resources.include_css("semantic-forms/static/style.css") }} - {% endblock notebook_css %} - - {%- block html_head_js_mathjax -%} - {{ mathjax(resources.mathjax_url) }} - {%- endblock html_head_js_mathjax -%} - - {%- endblock html_head -%} - -{%- endblock header -%} - - - - -{%- block body_header -%} - - -
- Skip to Main Content - Skip to Accessibility Settings - - -
-
-
- -
- - - - - - - - - - - - - - - - - - - - - {%- endblock body_header -%} - {% block body_loop %} - {% for cell in nb.cells %} - {% block anycell scoped %} - {{cell_row(cell, nb, resources)}} - {% endblock anycell %} - {% endfor %} - {% endblock body_loop %} - {%- block body_footer -%} - - - - - - - - - -
execution countsourceoutputscell typemetadatatoolbar
-
-
- Metadata - -
-
-
- - -{%- endblock body_footer -%} - -{% block footer %} -{% block footer_js %} -{{resources.include_js("semantic-forms/static/script.js")}} -{% endblock footer_js %} -{{ super() }} - - -{% endblock footer %} +{% block body_loop %} + + + + + + + + + + + + + + + + + + + + + {{super()}} + + + + + + + + + +
execution countsourceoutputscell typemetadatatoolbar
+{% endblock body_loop %} + + +{% block any_cell %} +{{cell_row(cell, nb, resources)}} +{% endblock any_cell %} {% macro highlight(body, type) %} {{markdown("```{{type}}\n" + json.dumps(nb.metadata, indent=2) + "\n```\n")}} @@ -177,11 +87,11 @@ -
{% 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 %} -
+ {% endmacro %} diff --git a/pyproject.toml b/pyproject.toml index 036bc44b..a2479072 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -130,12 +130,13 @@ notebooks = [ "user-tests/2-content/Imaging_Sky_Background_Estimation.ipynb", ] configurations = [ - "tests/configurations/default.py", - "tests/configurations/contenteditable-code.py", - "tests/configurations/tabs-scroll-to-top.py", - "tests/configurations/tab-to-content-nav-high-contrast.py", - "tests/configurations/tab-to-code-nav-high-contrast.py", + # "tests/configurations/default.py", + # "tests/configurations/contenteditable-code.py", + # "tests/configurations/tabs-scroll-to-top.py", + # "tests/configurations/tab-to-content-nav-high-contrast.py", + # "tests/configurations/tab-to-code-nav-high-contrast.py", "tests/configurations/table-default.py", + # "tests/configurations/notebook-list.py", ] [tool.doit.tasks.convert] From f9413fa93ebd63c6c5fde1f1a6a34237cc517be8 Mon Sep 17 00:00:00 2001 From: tonyfast Date: Fri, 12 May 2023 18:01:05 -0700 Subject: [PATCH 02/36] add templates for multiple conformations of notebooks --- .../templates/semantic-forms/forms.html.j2 | 61 +++++++++++++++++++ .../templates/semantic-forms/index.html.j2 | 30 +++++++++ .../templates/semantic-forms/ol.html.j2 | 13 ++++ .../templates/semantic-forms/sections.html.j2 | 10 +++ .../templates/semantic-forms/ul.html.j2 | 13 ++++ 5 files changed, 127 insertions(+) create mode 100644 nbconvert_html5/templates/semantic-forms/forms.html.j2 create mode 100644 nbconvert_html5/templates/semantic-forms/index.html.j2 create mode 100644 nbconvert_html5/templates/semantic-forms/ol.html.j2 create mode 100644 nbconvert_html5/templates/semantic-forms/sections.html.j2 create mode 100644 nbconvert_html5/templates/semantic-forms/ul.html.j2 diff --git a/nbconvert_html5/templates/semantic-forms/forms.html.j2 b/nbconvert_html5/templates/semantic-forms/forms.html.j2 new file mode 100644 index 00000000..33670a8d --- /dev/null +++ b/nbconvert_html5/templates/semantic-forms/forms.html.j2 @@ -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) %} +
+ {{cell_type_cell(cell)}} + +
+{{cell_toolbar(cell, ID)}} + + {% 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 %} + +{{cell.execution_count or ""}} +{{outputs_cell(cell, ID)}} +{% endmacro %} + + +{% macro cell_type_cell(cell) %} +{% set cell_type = cell.cell_type %} + +{% 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) %} + + + + +{% endmacro %} + +{% macro hide(x) %}{% if not x %}hidden{% endif %}{% endmacro %} \ No newline at end of file diff --git a/nbconvert_html5/templates/semantic-forms/index.html.j2 b/nbconvert_html5/templates/semantic-forms/index.html.j2 new file mode 100644 index 00000000..55420c64 --- /dev/null +++ b/nbconvert_html5/templates/semantic-forms/index.html.j2 @@ -0,0 +1,30 @@ +{%- extends 'semantic-forms/base.html.j2' -%} +{% from 'mathjax.html.j2' import mathjax %} +{% from 'jupyter_widgets.html.j2' import jupyter_widgets %} + +{% block body_header %} + +
+ {% block skip_links %}Skip to Main Content{% endblock skip_links %} + {% block site_header %}{% endblock site_header %} + + +
+
+
{% block nb_header %}{% endblock nb_header %}
+{% endblock body_header %} + + +{% block body_footer %} +
{% block site_footer %}{% endblock site_footer %}
+
+ +{% endblock body_footer %} + +{% block footer %} +{% block footer_js %} +{% endblock footer_js %} +{{ super() }} + +{% endblock footer %} + diff --git a/nbconvert_html5/templates/semantic-forms/ol.html.j2 b/nbconvert_html5/templates/semantic-forms/ol.html.j2 new file mode 100644 index 00000000..6cbfba53 --- /dev/null +++ b/nbconvert_html5/templates/semantic-forms/ol.html.j2 @@ -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 %} +
    {{super()}}
+{% endblock body_loop %} + +{% block any_cell %} +
  • +{{cell_form(cell, nb)}} +
  • +{% endblock any_cell %} \ No newline at end of file diff --git a/nbconvert_html5/templates/semantic-forms/sections.html.j2 b/nbconvert_html5/templates/semantic-forms/sections.html.j2 new file mode 100644 index 00000000..b4bd15c7 --- /dev/null +++ b/nbconvert_html5/templates/semantic-forms/sections.html.j2 @@ -0,0 +1,10 @@ +{%- extends 'semantic-forms/index.html.j2' -%} +{% from 'mathjax.html.j2' import mathjax %} +{% from 'jupyter_widgets.html.j2' import jupyter_widgets %} + + +{% block any_cell %} +
    +{{cell_form(cell, nb)}} +
    +{% endblock any_cell %} \ No newline at end of file diff --git a/nbconvert_html5/templates/semantic-forms/ul.html.j2 b/nbconvert_html5/templates/semantic-forms/ul.html.j2 new file mode 100644 index 00000000..df3a0a8f --- /dev/null +++ b/nbconvert_html5/templates/semantic-forms/ul.html.j2 @@ -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 %} + +{% endblock body_loop %} + +{% block any_cell %} +
  • +{{cell_form(cell, nb)}} +
  • +{% endblock any_cell %} \ No newline at end of file From 8a11b2d3f3af3837fd603366661402395110fada Mon Sep 17 00:00:00 2001 From: tonyfast Date: Fri, 12 May 2023 18:10:18 -0700 Subject: [PATCH 03/36] add more configurations to test the extent --- pyproject.toml | 8 ++++++-- tests/configurations/feed.py | 6 ++++++ tests/configurations/ol.py | 6 ++++++ tests/configurations/sections.py | 6 ++++++ tests/configurations/ul.py | 6 ++++++ 5 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tests/configurations/feed.py create mode 100644 tests/configurations/ol.py create mode 100644 tests/configurations/sections.py create mode 100644 tests/configurations/ul.py diff --git a/pyproject.toml b/pyproject.toml index a2479072..e00ddec2 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -130,12 +130,16 @@ notebooks = [ "user-tests/2-content/Imaging_Sky_Background_Estimation.ipynb", ] configurations = [ - # "tests/configurations/default.py", + "tests/configurations/default.py", # "tests/configurations/contenteditable-code.py", - # "tests/configurations/tabs-scroll-to-top.py", + "tests/configurations/tabs-scroll-to-top.py", # "tests/configurations/tab-to-content-nav-high-contrast.py", # "tests/configurations/tab-to-code-nav-high-contrast.py", "tests/configurations/table-default.py", + "tests/configurations/sections.py", + "tests/configurations/ol.py", + "tests/configurations/ul.py", + "tests/configurations/feed.py", # "tests/configurations/notebook-list.py", ] diff --git a/tests/configurations/feed.py b/tests/configurations/feed.py new file mode 100644 index 00000000..7db5a35d --- /dev/null +++ b/tests/configurations/feed.py @@ -0,0 +1,6 @@ +"""export notebooks as a feed of articles""" + +c.CSSHTMLHeaderPreprocessor.style = "github-light-colorblind" +c.NbConvertApp.export_format = "html5" +c.CSSHTMLHeaderPreprocessor.style = "default" +c.TemplateExporter.template_file = "semantic-forms/feed.html.j2" \ No newline at end of file diff --git a/tests/configurations/ol.py b/tests/configurations/ol.py new file mode 100644 index 00000000..4308d87f --- /dev/null +++ b/tests/configurations/ol.py @@ -0,0 +1,6 @@ +"""export notebooks as an order list of forms""" + +c.CSSHTMLHeaderPreprocessor.style = "github-light-colorblind" +c.NbConvertApp.export_format = "html5" +c.CSSHTMLHeaderPreprocessor.style = "default" +c.TemplateExporter.template_file = "semantic-forms/ol.html.j2" \ No newline at end of file diff --git a/tests/configurations/sections.py b/tests/configurations/sections.py new file mode 100644 index 00000000..662465cb --- /dev/null +++ b/tests/configurations/sections.py @@ -0,0 +1,6 @@ +"""export notebooks as regions of forms""" + +c.CSSHTMLHeaderPreprocessor.style = "github-light-colorblind" +c.NbConvertApp.export_format = "html5" +c.CSSHTMLHeaderPreprocessor.style = "default" +c.TemplateExporter.template_file = "semantic-forms/sections.html.j2" \ No newline at end of file diff --git a/tests/configurations/ul.py b/tests/configurations/ul.py new file mode 100644 index 00000000..fd7e43c5 --- /dev/null +++ b/tests/configurations/ul.py @@ -0,0 +1,6 @@ +"""export notebooks as an unordered list of forms""" + +c.CSSHTMLHeaderPreprocessor.style = "github-light-colorblind" +c.NbConvertApp.export_format = "html5" +c.CSSHTMLHeaderPreprocessor.style = "default" +c.TemplateExporter.template_file = "semantic-forms/ul.html.j2" \ No newline at end of file From 8548eefe3b0be370d0eec086cbecc4da3237a4c7 Mon Sep 17 00:00:00 2001 From: tonyfast Date: Fri, 12 May 2023 18:26:07 -0700 Subject: [PATCH 04/36] make template file configurable --- nbconvert_html5/form_exporter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nbconvert_html5/form_exporter.py b/nbconvert_html5/form_exporter.py index d7d53cd9..606487ef 100644 --- a/nbconvert_html5/form_exporter.py +++ b/nbconvert_html5/form_exporter.py @@ -15,6 +15,7 @@ import builtins import bs4 import pygments +from traitlets import Unicode import nbconvert_html5 import pydantic import nbformat.v4 @@ -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): From 5ea6c415b7c44ebcdd484b1695e5fb96e9f0b757 Mon Sep 17 00:00:00 2001 From: tonyfast Date: Fri, 26 May 2023 12:05:10 -0700 Subject: [PATCH 05/36] cleaner sections template --- .../templates/semantic-forms/base.html.j2 | 100 +++++++++--------- .../templates/semantic-forms/index.html.j2 | 25 +++-- .../templates/semantic-forms/sections.html.j2 | 28 ++++- 3 files changed, 93 insertions(+), 60 deletions(-) diff --git a/nbconvert_html5/templates/semantic-forms/base.html.j2 b/nbconvert_html5/templates/semantic-forms/base.html.j2 index 59a540f6..6a761914 100644 --- a/nbconvert_html5/templates/semantic-forms/base.html.j2 +++ b/nbconvert_html5/templates/semantic-forms/base.html.j2 @@ -175,54 +175,54 @@ var element = $('#{{ div_id }}'); -{% macro cell_form(cell, nb) %} -{% set count = nb["cells"].index(cell) +1%} -{% set ID = "/cells/" + str(cell.id or count) %} -
    - {{cell_type_cell(cell)}} -